1. ホーム
  2. sql

[解決済み] SQL NOT IN が機能しない

2023-07-30 18:27:49

質問

2 つのデータベースがあります。1 つは在庫を保持し、もう 1 つはプライマリ データベースのレコードのサブセットを保持するデータベースです。

次の SQL 文は動作しません。

SELECT  stock.IdStock
        ,stock.Descr       
FROM    [Inventory].[dbo].[Stock] stock
WHERE   stock.IdStock NOT IN
        (SELECT foreignStockId FROM
         [Subset].[dbo].[Products])

not in は機能しません。NOT を削除すると、正しい結果、つまり両方のデータベースにある製品が返されます。しかし、NOT IN を使用すると、まったく結果が返されません。

私は何を間違えているのでしょうか、何かアイデアはありますか?

どのように解決するのですか?

SELECT foreignStockId
FROM   [Subset].[dbo].[Products]  

おそらく NULL .

A NOT IN クエリは、もし NULL のリストに 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 で使用されているからです。述語は以下のように評価されます。 True , False または Unknown .

A 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 と評価されます。 三値論理の真理値表 .

次のリンクは、さまざまなオプションのパフォーマンスに関する追加的な議論を含んでいます。