Reputation: 13155
I need to find all id's from the OldTable that doesn't exist in the NewTable
Why won't this query find the id?
SELECT old_id FROM OldTable WHERE old_id NOT IN (
SELECT id FROM NewTable)
By them selves they return this
--Returns the id 18571
SELECT old_id FROM OldTable WHERE old_id = 18571
--Returns nothing
SELECT id FROM NewTable WHERE id = 18571
Am I missing something obvious here?
Both columns are of type int
and primary keys.
SOLVED
The id column had null's in them, I was just being ignorant =/
These works:
SELECT old_id FROM OldTable EXCEPT SELECT id FROM NewTable
SELECT * FROM old_table ot WHERE NOT EXISTS (
SELECT * FROM new_table nt WHERE nt.id = ot.old_id)
These doesn't work:
SELECT old_id FROM OldTable LEFT JOIN NewTable ON old_id = id WHERE id IS NULL
SELECT old_id FROM OldTable WHERE old_id NOT IN (
SELECT id FROM NewTable)
Upvotes: 4
Views: 6900
Reputation: 57093
The difference can be attributed to the presence of nulls.
Consider these two simplified queries, noting the predicate for both is NULL = 1
which evaluates to UNKNOWN which is handled differently by NOT EXISTS
and NOT IN
respectively:
SELECT *
FROM OldTable
WHERE NULL NOT IN (SELECT 1 FROM OldTable);
SELECT *
FROM OldTable
WHERE NOT EXISTS (SELECT * FROM OldTable WHERE NULL = 1);
The first returns no rows because NOT IN (subquery)
evaluated to FALSE.
The first returns all rows because NOT EXISTS (subquery)
evaluated to TRUE.
Conclusion: avoid nulls.
Upvotes: 2
Reputation:
select oldtable.id as orginal, newtable.id as new
from oldtable
left outer join newtable
on oldtable.id =newtable.id
where new is null
AFAIK (and i am not an expert - check my rep ;-) left outer join is a good technique for this.. it will may perform a not in and does not require a sub-select
@onedaywhen kindly points out that this is not always the case e.g. in SQL Server EXISTS() can be more efficient.
Upvotes: 0
Reputation: 44250
SELECT * FROM old_table ot
WHERE NOT EXISTS (
SELECT * FROM new_table nt
WHERE nt.new_key = ot.old_key
);
Upvotes: 2
Reputation: 11240
I don't know why your query doesn't give you the desired result, but I do know that using NOT IN
is not very efficient. You would be better of using a joins:
SELECT old_id
FROM OldTable
LEFT JOIN NewTable
ON old_id = id
WHERE id IS NULL
Upvotes: 1
Reputation: 11926
SELECT old_id FROM OLDTable WHERE id not in (SELECT id from NewTable);
You are using old_id in where condition in the first query and you are using id in second query
Upvotes: 0