SELECT foreignStockId
FROM [Subset].[dbo].[Products]
Retourneert waarschijnlijk een NULL
.
EEN NOT IN
query retourneert geen rijen als die er zijn NULL
s bestaat in de lijst met NOT IN
waarden. Je kunt ze expliciet uitsluiten met IS NOT NULL
zoals hieronder.
SELECT stock.IdStock,
stock.Descr
FROM [Inventory].[dbo].[Stock] stock
WHERE stock.IdStock NOT IN (SELECT foreignStockId
FROM [Subset].[dbo].[Products]
WHERE foreignStockId IS NOT NULL)
Of herschrijf met NOT EXISTS
in plaats daarvan.
SELECT stock.idstock,
stock.descr
FROM [Inventory].[dbo].[Stock] stock
WHERE NOT EXISTS (SELECT *
FROM [Subset].[dbo].[Products] p
WHERE p.foreignstockid = stock.idstock)
Evenals het hebben van de semantiek die u wilt hebben voor het uitvoeringsplan voor NOT EXISTS
is vaak eenvoudiger zoals hier wordt bekeken.
De reden voor het verschil in gedrag is te wijten aan de drie gewaardeerde logica die in SQL wordt gebruikt. Predikaten kunnen evalueren tot True
, False
, of Unknown
.
Een WHERE
clausule moet resulteren in True
om de rij te retourneren, maar dit is niet mogelijk met NOT IN
wanneer NULL
is aanwezig zoals hieronder uitgelegd.
'A' NOT IN ('X','Y',NULL)
is gelijk aan 'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)
- 'A' <> 'X' =
True
- 'A' <> 'Y' =
True
- 'A' <> NULL =
Unknown
True AND True AND Unknown
evalueert tot Unknown
volgens de waarheidstabellen voor drie gewaardeerde logica.
De volgende links bevatten wat aanvullende discussie over de prestaties van de verschillende opties.
- Moet ik
NOT IN
gebruiken? ,OUTER APPLY
,LEFT OUTER JOIN
,EXCEPT
, ofNOT EXISTS
? NOT IN
vs.NOT EXISTS
vs.LEFT JOIN / IS NULL
:SQL ServerLeft outer join
vsNOT EXISTS
NOT EXISTS
vsNOT IN