SELECT foreignStockId
FROM [Subset].[dbo].[Products]
Returnerer sandsynligvis en NULL .
En NOT IN forespørgsel vil ikke returnere nogen rækker, hvis nogen NULL s findes på listen over NOT IN værdier. Du kan eksplicit ekskludere dem ved at bruge IS NOT NULL som nedenfor.
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)
Eller omskriv med NOT EXISTS i stedet.
SELECT stock.idstock,
stock.descr
FROM [Inventory].[dbo].[Stock] stock
WHERE NOT EXISTS (SELECT *
FROM [Subset].[dbo].[Products] p
WHERE p.foreignstockid = stock.idstock)
Samt at have den semantik, at du vil have udførelsesplanen for NOT EXISTS er ofte enklere som set her.
Årsagen til forskellen i adfærd er ned til de tre værdifulde logikker, der bruges i SQL. Prædikater kan evalueres til True , False , eller Unknown .
En WHERE klausul skal evalueres til True for at rækken skal returneres, men det er ikke muligt med NOT IN når NULL er til stede som forklaret nedenfor.
'A' NOT IN ('X','Y',NULL) svarer til 'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)
- 'A' <> 'X' =
True - 'A' <> 'Y' =
True - 'A' <> NULL =
Unknown
True AND True AND Unknown evalueres til Unknown ifølge sandhedstabellerne for tre værdifulde logikker.
De følgende links har nogle yderligere diskussioner om de forskellige muligheders ydeevne.
- Skal jeg bruge
NOT IN,OUTER APPLY,LEFT OUTER JOIN,EXCEPT, ellerNOT EXISTS? NOT INvs.NOT EXISTSvs.LEFT JOIN / IS NULL:SQL ServerLeft outer joinvsNOT EXISTSNOT EXISTSvsNOT IN