SQL Select from two tables with Prio - sql

SELECT
t.id,
a.name
FROM table1 a, table2 t
WHERE a.id = t.id
What I actually get:
id | name
1 | Foo
1 | Bar
2 | Bar
I want the following results:
If Foo exists I want foo as result.
If Foo does not exists then Bar
So that prio 1 is foo, and prio 2 is bar.
id | name
1 | Foo
2 | Bar

Simplest way seems to be:
SELECT
t.id, a.name
FROM table1 a, table2 t
WHERE
(a.id = t.id and a.name = 'Foo')
OR
(a.id = t.id and a.name = 'Bar'
and t.id not in (SELECT id from table1 x where x.name ='Foo')
)
http://sqlfiddle.com/#!9/cb2c86/1

Simply use the following by using suggested ANSI JOIN syntax :
SELECT t.id, max(a.name) name
FROM table1 a JOIN table2 t on ( a.id = t.id )
GROUP BY t.id;
SQL Fiddle Demo

You don't actually need a join for this query:
SELECT a.id, a.name
FROM table1 a
WHERE a.name = 'Foo'
UNION ALL
SELECT a.id, a.name
FROM table1 a
WHERE a.name = 'Bar' AND
NOT EXISTS (SELECT 1 FROM table1 aa WHERE aa.id = a.id AND aa.name = 'Foo');

You can use ranking function if your DBMS support
select t.*
from (SELECT t.id, a.name,
row_number() over (partition by t.id
order by (case when a.name = 'Foo' then 0
when a.name = 'Bar' then 1
else 2
end)) Seq
FROM table1 a
inner join table2 t on a.id = t.id
) t
where Seq = 1;

Related

Fill a select with null when join isn't possible

I'm trying to do a select in n tables and show a few columns of each, but sometimes I can't match some columns and instead of getting a line with "null" the entire line is omitted.
For example:
table_a
id
...
1
2
3
table_b
id
name
...
1
a1
...
2
b2
...
3
c3
...
table_c
name
...
a1
...
And then I do the following select:
select
a.id,
c.name
from
table_a a,
table_b b,
table_c
where
( 1 = 1 )
and a.id = b.id
and b.name = c.name
I'm geting:
id
name
...
1
a1
...
I'm looking for:
id
name
...
1
a1
...
2
null
...
3
null
...
How do I do that? I checked a few answers around including this one but I didn't get how to solve it.
You can use an OUTER JOIN:
SELECT a.id,
c.name
FROM table_a a
LEFT OUTER JOIN table_b b
ON (a.id = b.id)
LEFT OUTER JOIN table_c c
ON (b.name = c.name)
or, depending on precedence of the joins:
SELECT a.id,
c.name
FROM table_a a
LEFT OUTER JOIN (
table_b b
INNER JOIN table_c c
ON (b.name = c.name)
)
ON (a.id = b.id)
Which, for the sample data:
CREATE TABLE table_a (id) AS
SELECT 1 FROM DUAL UNION ALL
SELECT 2 FROM DUAL UNION ALL
SELECT 3 FROM DUAL;
CREATE TABLE table_b (id, name) AS
SELECT 1, 'a1' FROM DUAL UNION ALL
SELECT 2, 'b1' FROM DUAL UNION ALL
SELECT 3, 'c1' FROM DUAL;
CREATE TABLE table_c (name) AS
SELECT 'a1' FROM DUAL;
Would both output:
ID
NAME
1
a1
2
null
3
null
fiddle
You should use a left join, not sure on oracle specifically but it would look something like:
select
a.id,
c.name
from
table_a a
LEFT JOIN table_b b ON (a.id = b.id)
LEFT JOIN table_c c ON (b.name = c.name)

Query for finding duplicate records where 2nd field is different

Probably very simple but given data of
TableA
FIELD1 | FIELD2
A | 1
A | 1
A | 2
B | 3
B | 3
C | 4
C | 5
How can I find the duplicate of Field 1 where Field 2 is different.
e.g from data above I want to return records 3 (A2) and 6 (C5)
Thanks in advance
You can use the following:
SELECT t1.* FROM table_name t1 INNER JOIN (
SELECT FIELD1, MIN(FIELD2) AS FIELD2
FROM table_name
GROUP BY FIELD1
) t2 ON t1.FIELD1 = t2.FIELD1 AND t1.FIELD2 <> t2.FIELD2
demo on dbfiddle.uk
You can use exists:
select a.*
from tableA a
where a.field2 > (select min(a2.field2)
from tableA a2
where a2.field1 = a.field1
);
You could also use window functions:
select a.*
from (select a.*,
min(a.field2) over (partition by field1) as min_field2
from tableA a
) a
where field2 > min_field2;

Return matching rows only SQL Server

I am sure this simple but i am really stuck. Here is a example of the resultset i want from two tables that have the same structure and in this case data or records
TableA
Ref cola colb id
------------------
1 a b 14
1 a b 24
TableB
Ref cola colb id
------------------
1 a b 1
1 a b 2
1 a b 3
Expected result:
Ref cola colb id Ref1 cola1 colb1 id1
----------------------------------------
1 a b 14 1 a b 1
1 a b 24 1 a b 2
Use:
SELECT *
FROM table1 t1
JOIN Table2 t2
ON t1.Ref =t2.Ref AND t1.cola = t2.cola
AND t1.colb = t2.colb AND t1.id = t2.id
or
SELECT *
FROM table1 t1
JOIN Table2 t2
USING ( Ref , cola , colb, id )
one more way would be
;with cte
as
(
select Ref, cola, colb, id,
hashbytes('sha1',concat(Ref, cola, colb)) as tb1hash
from table1
)
select
t1.Ref, --all required cols
from cte c
join
(
select Ref, cola, colb, id,
hashbytes('sha1',concat(Ref, cola, colb)) as tb2hash
from table2
) b
on
b.tb2hash=c.tb1hash
Guessing:
;WITH TableAWithRowNum
AS (
SELECT *, ROW_NUMBER(ORDER BY id) AS RowNum
FROM dbo.TableA
), TableBWithRowNum
AS (
SELECT *, ROW_NUMBER(ORDER BY id) AS RowNum
FROM dbo.TableB
)
SELECT a.*, b.*
FROM TableAWithRowNum a
INNER JOIN TableBWithRowNum b ON a.Ref = b.Ref
--AND other join predicates on ColA, ... etc.
AND a.RowNum = b.RowNum

SQL inner join if not found omit condition

SQL inner join if not found omit condition
Suppose I have a SQL query like:
SELECT A.* FROM Table_A A
INNER JOIN Table_B B ON A.Field1 = B.Field1 AND A.Field2 = B.Field2
WHERE A.Field3 > 10
What I'd like to achieve is, we first inner join by Field1/Field2, if no data found only join by Field1.
What's the proper way to this?
Table A:
Id Field1 Field2 Field3
1 a b 12
2 a c 13
3 e f 14
2 d c 15
Table B:
Id Field1 Field2
1 a b
2 e g
Result should be:
Id Field1 Field2 Field3
1 a b 12
3 e f 14
First part of the union is your original. Second part joins only on the first set of fields in cases where there is no match for both sets of fields.
SELECT * FROM Table_A A
INNER JOIN Table_B B ON A.Field1 = B.Field1 AND A.Field2 = B.Field2
WHERE A.Field3 > 10
UNION
SELECT * FROM Table_A A
INNER JOIN Table_B B ON A.Field1 = B.Field1
WHERE A.Field3 > 10
AND NOT EXISTS
(SELECT 1 FROM TABLE_B B2
WHERE A.Field1 = B2.Field1 AND A.Field2 = B2.Field2);
You can join on the same table twice, one with inner join and one with left join and put the conditional logic on the left join.
select distinct t1.*
from table1 t1
left join table2 t2 on t1.f2 = t2.f2
inner join table2 t3 on t1.f1 = t3.f1
You can use CASE in INNER JOIN. Just check this :
declare #a table (col1 int, col2 int, col3 int)
declare #b table (col1 int, col2 int, col3 int)
Insert into #a values(1,1,11),(2,2,15),(3,4,20),(4,5,9)
Insert into #b values(1,1,5),(2,2,2),(3,3,20),(4,5,20)
select A.* from #a A inner join #b B on
(CASE
WHEN A.col2 = B.col2 then 1
WHEN A.col2 <> B.col2 then 1
ELSE 1
END) = 1 and A.col1 = B.col1
where A.col3 > 10
You could try the following query:
SELECT ta.*
FROM #Table_A ta
INNER JOIN #Table_B tb ON ta.Field1 = tb.Field1
WHERE ta.Field3 > 10
AND
(
ta.Field2 = tb.Field2
OR
NOT EXISTS (
SELECT 1 FROM #Table_A ta2
INNER JOIN #Table_B tb2 ON ta2.Field1 = tb2.Field1 AND ta2.Field2 = tb2.Field2
WHERE ta2.Field1 = ta.Field1
)
)
Demo link: http://rextester.com/DKRG30176
;With Tab1(Id,Field1, Field2, Field3)
AS
(
SELECT 1,'a','b',12 Union all
SELECT 2,'a','c',13 Union all
SELECT 3,'e','f',14 Union all
SELECT 2,'d','c',15
)
,Tab2 (Id, Field1, Field2)
AS
(
SELECT 1,'a','b' Union ALL
SELECT 2,'e','g'
)
SELECT Id,Field1, Field2, Field3 From Tab1
EXCEPT
SELECT Id
,Field1
,Field2
,Field3
FROM (
SELECT I.Id
,i.Field1
,i.Field2
,i.Field3
,COUNT(i.Id) OVER (
PARTITION BY i.Id ,i.Field1, i.Field2 ORDER BY i.Id
) Seq
FROM Tab1 i
LEFT JOIN Tab2 o ON i.Id = o.Id
WHERE i.Field1 !=o.Field1 AND i.Field2 !=o.Field2
) Dt
WHERE Dt.Seq = 1 AND Dt.Field3 > 10
OutPut
Id Field1 Field2 Field3
---------------------------
1 a b 12
3 e f 14

Fetch records from two tables in sql server

I have two table in sql server like this .
table 1
userid value
a 1
b 1
c 1
d 1
table 2
userid value
e 0
f 0
g 0
a 0
b 0
I want to output like this from above two tables
usrid value
a 0
b 0
c 1
d 1
e 0
f 0
g 0
if any records exists in table 1, records must fetches the data from table 2, other wise table 1. if userid not exists in table 1 and fetches records from table 2 only.
Try this:
select ISNULL(t1.usrid,t2.usrid) as usrid
,ISNULL(t1.value,t2.value) as value
from table1 t1
outer join table2 t2 on t1.usrid = t2.usrid
Try this
SELECT * FROM dbo.Table_2 AS t WHERE t.uid IN (SELECT t2.uid FROM dbo.Table_1 AS t2)
UNION
SELECT * FROM dbo.Table_1 AS t WHERE t.uid NOT IN (SELECT t2.uid FROM dbo.Table_2 AS t2)
UNION
SELECT * FROM dbo.Table_2 AS t WHERE t.uid NOT IN (SELECT t2.uid FROM dbo.Table_1 AS t2)
Try this
SELECT *
FROM table1
WHERE userid NOT IN (select userid from table2)
UNION
SELECT *
FROM table2
Try this:
SELECT *
FROM table1
WHERE table1.userid NOT IN (select userid from table2)
UNION
SELECT *
FROM table2