create table pk1(col1 int)
create table pk2(col1 int)
create table pk3(col1 int)
create table fk(col1 int, col2 int NOT NULL, col3 int, col4 int)
insert into pk1 values(1)
insert into pk1 values(2)
insert into pk1 values(3)
insert into pk2 values(1)
insert into pk2 values(2)
insert into pk2 values(3)
insert into pk3 values(1)
insert into pk3 values(2)
insert into pk3 values(3)
insert into fk values(1, 1, null, 10)
insert into fk values(null, 1, 1, 20)
insert into fk values(1, 1,null, 30)
insert into fk values(1, 1, null, 40)
insert into fk values(1, 1, 1, 70)
insert into fk values(2, 3, 1, 60)
insert into fk values(1, 1, 1, 100)
insert into fk values(2, 2, 3, 80)
insert into fk values(null, 1, 2, 50)
insert into fk values(null, 1, 4, 150)
insert into fk values(5, 1, 2, 250)
insert into fk values(6, 7, 8, 350)
insert into fk values(10, 1, null, 450)
Below query will give the result :
select fk.* from fk inner join pk1 on pk1.col1 = fk.col1 inner join pk2 on pk2.col1 = fk.col2 inner join pk3 on pk3.col1 = fk.col3
Result :
+++++
| col1 | col2 | col3 | col4 |
+++++
| 1 | 1 | 1 | 70 |
| 2 | 3 | 1 | 60 |
| 1 | 1 | 1 | 100 |
| 2 | 2 | 3 | 80 |
+++++
But I require also the NULL values in col1 and col3
Hence doing the below :
select distinct fk.* from fk inner join pk1 on pk1.col1 = fk.col1 or fk.col1 is null inner join pk2 on pk2.col1 = fk.col2 inner join pk3 on pk3.col1 = fk.col3 or fk.col3 is null
+++++
| col1 | col2 | col3 | col4 |
+++++
| null | 1 | 1 | 20 |
| null | 1 | 2 | 50 |
| 1 | 1 | null | 10 |
| 1 | 1 | null | 30 |
| 1 | 1 | null | 40 |
| 1 | 1 | 1 | 70 |
| 1 | 1 | 1 | 100 |
| 2 | 2 | 3 | 80 |
| 2 | 3 | 1 | 60 |
+++++
The above is the reqd output, but the query will be very slow if there are more NULL valued rows in col1 and col3, since I need to also use distinct if I use 'IS NULL' check in JOIN.
Please let me know if there is an aliternative to this query which can return the same result set in an efficient manner.
Hi
The
INNER JOIN ... ON <field1> = <field2> OR <field1> IS NULL
can be replaces with
LEFT OUTER JOIN .... ON <field1> = <field2>
And an INNER JOIN needs to precede all other joins , so the resulting SELECT will look like :
select distinct fk.*
from fk
inner join pk2
on k2.col1 = fk.col2
LEFT OUTER JOIN pk1
on pk1.col1 = fk.col1
LEFT OUTER JOIN pk3
on pk3.col1 = fk.col3
|||But the LEFT JOIN does not give the expected result(i,.e 9 rows) I have posted, it gives 12 rows which is not the expected result.|||SELECT DISTINCT fk.col1, fk.col2, fk.col3, fk.col4
FROM fk FULL OUTER JOIN
pk1 ON fk.col1 = pk1.col1 FULL OUTER JOIN
pk3 ON fk.col3 = pk3.col1 FULL OUTER JOIN
pk2 ON fk.col2 = pk2.col1
|||Example of using where clause to filter.
SELECT fk.col1, fk.col2, fk.col3, fk.col4
FROM fk FULL OUTER JOIN
pk1 ON fk.col1 = pk1.col1 FULL OUTER JOIN
pk3 ON fk.col3 = pk3.col1 FULL OUTER JOIN
pk2 ON fk.col2 = pk2.col1
WHERE (fk.col1 IS NULL) OR
(fk.col3 IS NULL)
No comments:
Post a Comment