SQL の NOT IN
句と NULL 値のトラブルシューティング
この記事では、SQL クエリで NOT IN
句を使用するときに発生する一般的な問題、つまり NULL 値が原因で予期せず空の結果セットが表示される問題について説明します。 このシナリオには、(Stock
データベース内の) Inventory
テーブルに存在しないレコードを (Products
データベース内の) Subset
テーブルから選択することが含まれます。
NOT IN
テーブルの foreignStockId
列に NULL 値が含まれている場合、Products
句は期待どおりに機能しません。 NOT IN
サブクエリの結果セットに NULL が 1 つでも存在すると、クエリ全体が行を返さなくなります。
解決策:
これを修正するには、NULL 値を明示的に除外する必要があります。 2 つの効果的なアプローチを紹介します:
1. IS NOT NULL
の使用:
このアプローチでは、NOT IN
サブクエリから 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
の使用:
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>
問題の理解: 3 つの値の論理
SQL は、True、False、Unknown の 3 つの値のロジックを使用します。 行を結果セットに含めるには、WHERE
句が True と評価される必要があります。 この問題は、'A' <> NULL
が Unknown
と評価されるために発生します。 Unknown
比較に NOT IN
が存在する場合、式全体が Unknown
になり、結果セットは空になります。
例:
次の点を考慮してください:
Predicate | True | False | Unknown |
---|---|---|---|
'A' NOT IN ('X','Y',NULL) |
True | True | Unknown |
Unknown
の結果は、'A' と NULL の比較から生じます。 したがって、WHERE
句全体が Unknown
と評価され、行は返されません。
IS NOT NULL
または NOT EXISTS
を使用することで、この曖昧さを回避し、クエリが意図した結果を返すようにします。 このようなシナリオでは、パフォーマンスと読みやすさが向上するため、NOT EXISTS
アプローチが好まれることがよくあります。
以上がSQL の「NOT IN」句が NULL 値で機能しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。