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