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 IN
vs.NOT EXISTS
vs.LEFT JOIN / IS NULL
:SQL ServerLeft outer join
vsNOT EXISTS
NOT EXISTS
vsNOT IN