These are rather basic statements. I have a list of graphics which are linked to items in another table. I want to check how many of the graphics are not in use and can theoretically be deleted.
So first I used the NOT IN clause:
SELECT [GraphicNr]
,[Graphicfile]
FROM [dbo].[Graphic]
WHERE graphicnr NOT IN (SELECT graphicnr FROM dbo.Komp)
Which gave zero results, which seemed weird to me. After rewriting it to a NOT EXISTS, I got about 600 results:
SELECT [GraphicNr]
,[Graphicfile]
FROM [dbo].[Graphic] a
WHERE NOT EXISTS (SELECT graphicnr FROM dbo.komp b WHERE a.GraphicNr = b.GraphicNr)
So I guess I don't really have a problem, since the second statement works, but to my understanding, shouldn't the first one give the same results?
That because of
NULL
value returned fromsubquery
:This would produce
no records
orno rows affected
because ofgraphicnr not in (null)
which is not desired output.So, the
NOT EXISTS
would not work as the way theIN
clause orNOT IN
work. It behaves differently thenIN
orNOT IN
clause.However, you can prevent this by using
IS NOT NULL
filter insubquery
. But the recommended way is to useNOT EXISTS
instead.NOT IN
with a subquery has strange behavior. If any row in the subquery returns aNULL
value, then no rows are returned. This is due to following the strict semantics ofNULL
(which means: "I don't know if they are equal").NOT EXISTS
behaves as you would expect. For this reason, I recommend never usingNOT IN
with a subquery. Always useNOT EXISTS
.