SQL Join with 2 columns when one of them is NULL/Blank - sql

Let's say I have 2 tables like this:
I want to join both #tmp1 & #tmp2 for Columns : Col2 & Col3 . But if the value of either of these columns is blank or Null, I want to ignore that column and just look at one.
So for example here, when I join where Col2 is ABC, I should get both DEF & Blank for Col3.
I hope I'm making some sense here. Apologize if it's not clear enough.

I can't tell from your example what columns you want to join but to solve the "null" problem you do it like this
SELECT *
FROM T1
JOIN T2 ON COALESCE(T1.COL1,T2.COL1) = T2.COL1
AND COALESCE(T1.COL2,T2.COL2) = T2.COL2
If T1.COL1 or T1.COL2 are null it will use the value of the table it is joining to. This allows null to be a "wildcard".
or if T2 is the table with nulls
SELECT *
FROM T1
JOIN T2 ON T1.COL1 = COALESCE(T2.COL1,T1.COL1)
AND T1.COL2 = COALESCE(T2.COL2,T1.COL2)

You can use union for this checking if at least 1 of the 2 columns is the same using exists:
select col1, col2, col3
from tmp1 t1
where exists (select 1
from tmp2 t2
where t1.col2 = t2.col2 or t1.col3 = t2.col3)
union
select col1, col2, col3
from tmp2 t2
where exists (select 1
from tmp1 t1
where t1.col2 = t2.col2 or t1.col3 = t2.col3)
Fiddle Demo
Results:
| col1 | col2 | col3 |
|-------|------|------|
| test1 | abc | def |
| test2 | aaa | bbb |
| test1 | abc | |
| test2 | ccc | bbb |

Related

SQL query to group multiple values

Can you let me how to build sql query for the below requirement:
I have 2 tables:
Table A:
col1 | Col2
------------
1 | a
2 | b
Table B:
Col1 | Col2
-----------
1 | 10
2 | 20
a | 30
b | 40
I need output like this:
Col1 | Col2
------------
1,a | 10,30
2,b | 20,40
Can anyone one help me please. Thanks
You can use this:
SELECT CONCAT(t1.col1, ' , ', t2.col1) AS Col1, CONCAT(t1.col2, ' , ', t2.col2) AS Col2
from
(select t1.col1, t2.col2 from tableA t1, tableB t2
where t1.col1 = t2.col1) as t1,
(select t1.col1 as col3, t2.col1, t2.col2 from tableA t1, tableB t2
where t1.col2 = t2.col1) as t2
where t1.col1 = t2.col3;
SQL Fiddle here:
http://sqlfiddle.com/#!9/459ae69/25
SQL DEMO
SELECT CONCAT(CONCAT(A."Col1", ' , '), A."Col2") AS Col1,
LISTAGG(B."Col2", ', ') WITHIN GROUP (ORDER BY B."Col1") Col2
FROM TableA A
JOIN TableB B
ON A."Col1" = B."Col1"
OR A."Col2" = B."Col1"
GROUP BY CONCAT(CONCAT(A."Col1", ' , '), A."Col2")
;
OUTPUT
| COL1 | COL2 |
|-------|--------|
| 1 , a | 10, 30 |
| 2 , b | 20, 40 |

SQL Compare Two tables with column value difference

I've 2 tables with exact same structure and I would like compare the column values and display in specific format. I'm new to SQL. I tried with Minus function but its not helping. Find below scenario
Table 1
Key Col1 Col2
1 110 AAA
2 120 BBB
Table 2
Key Col1 Col2
1 111 CCC
2 120 DDD
I need output in below format
Key Field Table1 Table2
1 Col1 110 111
1 Col2 AAA CCC
2 Col2 BBB DDD
How can this be accomplished?
Thanks,
Milind
This is an arcane structure for bringing the tables together. I think this will work:
select t1.col1,
(case when t2.key is not null then 'col2' else 'col1' end) as field,
(case when t2.key is not null then t1.col2
when seqnum = 1 then t1.col1
when seqnum = 2 then t1.col2
end) as Table1,
(case when t2.key is not null then t2.col2
when seqnum = 1 then t2.col1
when seqnum = 2 then t2.col2
end) as Table2
from table1 t1 left join
table2 t2
on t1.key = t2.key and t1.col1 = t2.col1 left join
(select tt2.*, row_number() over (partition by tt2.key order by tt2.key) as seqnum
from table2 tt2
) tt2
on t1.key = tt2.key and t2.key is null;

Merge columns and Sub Select list

My query simply looks like:
SELECT col1, col2,
(SELECT col3, col4 FROM Table2)
FROM Table1
Wanted result is:
col1 | col2 | col3 | col4
-------------------------
ABC | DEF | GHI | JKL
... | ... | ... | ...
But I am getting an error:
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
How to merge lists and current rows?
You probably want something like this:
SELECT col1,
col2,
(SELECT col3 FROM Table2 as t2 WHERE t2.id = t1.id) as col3,
(SELECT col4 FROM Table2 as t2 WHERE t2.id = t1.id) as col4
FROM Table1 as t1
or even better:
SELECT t1.col1,
t1.col2,
t2.col3,
t2.col4
FROM Table1 as t1
JOIN Table2 as t2
ON t1.id = t2.id
if you don't have a field to join both tables then:
SELECT t1.col1,
t1.col2,
t2.col3,
t2.col4
FROM Table1 as t1
CROSS JOIN Table2 as t2

SQL left outer join to a min value of right table

I have two tables, lets say table1 and table2.
table1 || table2
--------||-------------
col1 || col1 | col2
--------||------|------
a || a | 4
b || a | 2
c || a | 5
d || b | 1
|| b | 3
|| d | 6
With SELECT table1.col1, table2.col2 FROM table1 LEFT OUTER JOIN table2 ON table1.col1 = table2.col1 I get following:
table1.col1 | table2.col2
-------------|-------------
a | 4
a | 2
a | 5
b | 1
b | 3
c | NULL
d | 6
How is it possible to achieve this (only get the minimum of table2.col2 so that there's no entry of table1.col1 more than once):
table1.col1 | table2.col2
-------------|-------------
a | 2
b | 1
c | NULL
d | 6
Or is it a wrong approach?
You need to use MIN:
SELECT
t1.col1,
MIN(t2.col2) AS col2
FROM table1 t1
LEFT JOIN table2 t2
ON t2.col1 = t1.col1
GROUP BY t1.col1
SQL Fiddle
Alternative solution, use a correlated sub-query:
select col1, (select min(col2) from table2 t2 where t2.col1 = t1.col1)
from table1 t1
If there are more columns in table2 you may want to use APPLY operator:
SELECT * FROM table1
OUTER APPLY(SELECT TOP 1 * FROM table2
WHERE table1.col1 = table2.col1 ORDER BY table2.col2)oa

Comparing two tables with SQL

I need a query to produce a compare table between two tables.
Something like this:
table_1:
col1 | col2 | col3
a | 1 | a_comment
b | 2 | b_comment
table_2:
col1 | col2 | col3
a | 3 | a_comment
c | 4 | c_comment
Query result:
col1 | table_1.col2 | table_2.col2 | col3
a | 1 | 3 | a_comment
b | 2 | NULL | b_comment
c | NULL | 4 | c_comment
Also, I need to keep the order, s.t. if x in col1 is before y in col1 in any of the tables it will also be before it in the query result.
I tried to do it with FULL JOIN but it duplicates col1 and col3.
Thank you!
select t1.col1, t1.col2, t2.col2, t1.col3
from table_1 t1
left join table_2 t2
on t1.col1 = t2.col1
and t1.col3 = t2.col3
union
select t2.col1, t2.col2, t1.col2, t2.col3
from table_2 t2
left join table_1 t1
on t2.col1 = t1.col1
and t2.col3 = t1.col3
Full join is ok i think, you just have to select not all but just what you want, like
SELECT ISNULL(table_1.col1, table_2.col1) col1, table_1.col2, table2.col2, ISNULL(table_1.col3, table_2.col3) col3
ISNULL might be called different depending on what database system u use
SELECT col1
, t1.col2
, t2.col3
, col3
FROM table1 t1
FULL OUTER JOIN table2 t2
USING (col1, col3)