SQL の NOT IN
句と NULL 値の問題
SQL の NOT IN
演算子は、指定された値セット内で列の値が見つからない行を選択するように設計されています。ただし、比較セットに NULL
値が含まれている場合、この演算子は予期しない動作をします。この記事では、この動作について説明し、解決策を提供します。
問題:
サブセット データベース (Inventory
) には存在しない製品を 1 つのデータベース (Subset
) で検索しようとしているシナリオを考えてみましょう。 NOT IN
を使用した一般的なアプローチは次のようになります:
<code class="language-sql">SELECT stock.IdStock, stock.Descr FROM [Inventory].[dbo].[Stock] stock WHERE stock.IdStock NOT IN (SELECT foreignStockId FROM [Subset].[dbo].[Products]);</code>
サブクエリ (SELECT foreignStockId FROM [Subset].[dbo].[Products]
) が NULL
値を返す場合、NOT IN
に IdStock
値がある場合でも、[Inventory].[dbo].[Stock]
条件全体が不定になり、空の結果セットになります。 > は に存在しません。[Subset].[dbo].[Products]
これが起こる理由:
SQL は 3 つの値のロジック、、TRUE
、FALSE
を使用します。 値を UNKNOWN
と比較すると、結果は常に NULL
になります。 UNKNOWN
は基本的に、NOT IN
すべてFALSE
の比較で値が であるかどうかをチェックします。 は UNKNOWN
ではないため、サブクエリの結果セット内の FALSE
は、NULL
条件全体を空のセットとして評価します。NOT IN
解決策:
この問題を回避するには、次のいずれかの方法を使用します。
1. NULL を明示的に除外する: 値を除外するようにサブクエリを変更します:NULL
<code class="language-sql">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);</code>
2. を使用します:NOT EXISTS
このアプローチは、その明瞭さと効率の点で一般的に好まれます:
<code class="language-sql">SELECT stock.IdStock, stock.Descr FROM [Inventory].[dbo].[Stock] stock WHERE NOT EXISTS (SELECT * FROM [Subset].[dbo].[Products] p WHERE p.foreignStockId = stock.IdStock);</code>
句は、サブクエリ内に条件に一致する行が NOT EXISTS
存在しない かどうかをチェックします。 明示的な除外を必要とせずに、 値を正しく処理します。NULL
値と NULL
演算子の相互作用を理解することで、より堅牢で信頼性の高い SQL クエリを作成できます。 NOT IN
の代替案は、比較セット内の潜在的な NOT EXISTS
値を処理する場合に、よりクリーンで効率的なソリューションであることがよくあります。NULL
以上がサブクエリに NULL 値が存在する場合、SQL `NOT IN` クエリが結果を返さないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。