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