SELECT foreignStockId
FROM [Subset].[dbo].[Products]
Pravděpodobně vrací NULL
.
A NOT IN
dotaz nevrátí žádné řádky, pokud je NULL
s existuje v seznamu NOT IN
hodnoty. Můžete je explicitně vyloučit pomocí IS NOT NULL
jak je uvedeno níže.
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)
Nebo přepište pomocí NOT EXISTS
místo toho.
SELECT stock.idstock,
stock.descr
FROM [Inventory].[dbo].[Stock] stock
WHERE NOT EXISTS (SELECT *
FROM [Subset].[dbo].[Products] p
WHERE p.foreignstockid = stock.idstock)
Stejně jako mít sémantiku, kterou chcete, plán provádění pro NOT EXISTS
je často jednodušší, jak je uvedeno zde.
Důvodem rozdílu v chování je logika se třemi hodnotami použitá v SQL. Predikáty mohou být vyhodnoceny jako True
, False
nebo Unknown
.
A WHERE
klauzule musí být vyhodnocena jako True
aby byl řádek vrácen, ale to není možné s NOT IN
když NULL
je přítomen, jak je vysvětleno níže.
'A' NOT IN ('X','Y',NULL)
je ekvivalentní 'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)
- 'A' <> 'X' =
True
- 'A' <> 'Y' =
True
- 'A' <> NULL =
Unknown
True AND True AND Unknown
vyhodnotí jako Unknown
podle pravdivostních tabulek pro tři hodnotné logiky.
Následující odkazy obsahují další diskusi o výkonu různých možností.
- Mám použít
NOT IN
,OUTER APPLY
,LEFT OUTER JOIN
,EXCEPT
neboNOT EXISTS
? NOT IN
vs.NOT EXISTS
vs.LEFT JOIN / IS NULL
:SQL ServerLeft outer join
vsNOT EXISTS
NOT EXISTS
vsNOT IN