SELECT foreignStockId
FROM [Subset].[dbo].[Products]
おそらくNULLを返します 。
NOT IN NULLがある場合、クエリは行を返しません sはNOT INのリストに存在します 値。 IS NOT NULLを使用して、それらを明示的に除外できます 以下のように。
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)
または、NOT EXISTSを使用して書き直します 代わりに。
SELECT stock.idstock,
stock.descr
FROM [Inventory].[dbo].[Stock] stock
WHERE NOT EXISTS (SELECT *
FROM [Subset].[dbo].[Products] p
WHERE p.foreignstockid = stock.idstock)
NOT EXISTSの実行プランに必要なセマンティクスを用意するだけでなく ここで見られるように、多くの場合、より単純です。
動作の違いの理由は、SQLで使用される3値論理にあります。述語はTrueと評価できます 、False 、またはUnknown 。
WHERE 句はTrueに評価される必要があります 行が返されるようにするためですが、これはNOT INでは不可能です。 NULLの場合 以下に説明するように存在します。
'A' NOT IN ('X','Y',NULL) 'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)と同等です
- 'A' <>'X' =
True - 'A' <>'Y' =
True - 'A' <> NULL=
Unknown
True AND True AND Unknown Unknownと評価されます 3値論理の真理値表による。
次のリンクには、さまざまなオプションのパフォーマンスに関する追加の説明があります。
-
NOT INを使用する必要があります 、OUTER APPLY、LEFT OUTER JOIN、EXCEPT、またはNOT EXISTS? -
NOT INvs.NOT EXISTSvs.LEFT JOIN / IS NULL:SQL Server Left outer joinvsNOT EXISTSNOT EXISTSvsNOT IN