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 INgebruiken? ,OUTER APPLY,LEFT OUTER JOIN,EXCEPT, ofNOT EXISTS? NOT INvs.NOT EXISTSvs.LEFT JOIN / IS NULL:SQL ServerLeft outer joinvsNOT EXISTSNOT EXISTSvsNOT IN