I have a requirement where I have to extract data exclusive to the left table. I am using the left outer join for this. But the output extract data that has a null value for the variable used in join condition in both the table which is not expected. Below is the detailed condition,
TableA
id | name | subject |
---|---|---|
1 | tom | math |
2 | jack | null |
TableB
id | name | subject |
---|---|---|
3 | john | science |
2 | jack | null |
Query
SELECT *
FROM TableA
LEFT JOIN TableB
ON a.id = b.id
AND a.subject = b.subject
WHERE b.id IS NULL
AND b.subject IS NULL
Expected output
id | name | subject |
---|---|---|
1 | tom | math |
Actual output
id | name | subject |
---|---|---|
1 | tom | math |
2 | jack | null |
The problem is that, in your problem requirement, you seem to need to treat null
as equal to (other) null
.
This goes against the definition of null
. But you can achieve your required result - in the join condition, change
and a.subject = b.subject
to
and (a.subject = b.subject or (a.subject is null and b.subject is null))
In Oracle, you can do this more succintly:
and decode (a.subject, b.subject, 1) = 1
because decode
was defined intentionally to see two null
as "equal".
You could do the same for the id
column, if needed - but assuming it's supposed to be primary key in both tables, you shouldn't need it.
EDIT The OP claims that the suggested use of decode
produces the wrong result, while the explicit use of or (a.subject is null and b.subject is null)
runs indefinitely on SQL Developer. So in this Edit I will show that the OP's claims are both wrong. (I ran everything on my copy of SQL Developer, so the IDE is not the issue.)
What he is doing, we don't know, but both suggestions are 100% correct for the data provided and the query as given to us (after we add the table aliases, which are missing in the OP's query, and we select just the data from TableA
).
Test data:
create table tablea (id, name, subject) as
select 1, 'tom' , 'math' from dual union all
select 2, 'jack', null from dual
;
create table tableb (id, name, subject) as
select 3, 'john', 'science' from dual union all
select 2, 'jack', null from dual
;
First query and result:
SELECT a.*
FROM TableA a
LEFT JOIN TableB b
ON a.id = b.id
AND (a.subject = b.subject or (a.subject is null and b.subject is null))
WHERE b.id IS NULL
AND b.subject IS NULL
;
ID NAME SUBJECT
---------- ---- -------
1 tom math
Second query and result:
SELECT a.*
FROM TableA a
LEFT JOIN TableB b
ON a.id = b.id
AND decode(a.subject, b.subject, 1) = 1
WHERE b.id IS NULL
AND b.subject IS NULL
;
ID NAME SUBJECT
---------- ---- -------
1 tom math
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.