SQL 的 NOT IN
子句與 NULL 值問題
SQL 中的 NOT IN
運算子旨在選擇在指定值集中未找到列值的行。但是,當比較集包含 NULL
值時,此運算子會出現意外行為。本文解釋了此行為並提供了解決方案。
問題:
考慮這樣一個場景,您嘗試在一個資料庫 (Inventory
) 中尋找子集資料庫 (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 使用三值邏輯: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
子句檢查子查詢中是否存在與條件相符的 no 行。 它可以正確處理 NULL
值,無需明確排除。
透過了解 NULL
值和 NOT IN
運算子之間的交互,您可以編寫更強壯、更可靠的 SQL 查詢。 在處理比較集中的潛在 NOT EXISTS
值時,NULL
替代方案通常是更乾淨、更有效率的解決方案。
以上是當子查詢中存在 NULL 值時,為什麼我的 SQL'NOT IN”查詢沒有傳回結果?的詳細內容。更多資訊請關注PHP中文網其他相關文章!