對 SQL 的 NOT IN
子句進行故障排除:為什麼它可能會失敗以及如何修復它
SQL 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])</code>
此查詢可能不會傳回任何結果,即使它應該排除某些記錄。
根本原因:NULL
價值觀
問題源自於 NULL
表的 foreignStockId
欄位中的 Products
值。 SQL 的 NOT IN
運算子與 NULL
的行為無法預測。 涉及 NULL
的比較總是會產生 UNKNOWN
,這反過來會影響 WHERE
子句的整體布林邏輯。
有效的解決方案:
這裡有兩種可靠的方法來修正這個問題:
NULL
s: 修改子查詢以明確排除 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>
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
比較的複雜性。
效能最佳化:
雖然兩種解決方案都是正確的,但它們的性能可能會有所不同。 NOT EXISTS
通常會導致更簡單且可能更快的執行計劃,尤其是對於大型資料集。 但是,如果您的 foreignStockId
列沒有 NULL
值,則 NOT IN
的效能可能會稍好一些。 最好在您的特定環境中測試這兩種方法以確定最佳解決方案。
以上是為什麼我的SQL NOT IN子句無法回傳預期結果?的詳細內容。更多資訊請關注PHP中文網其他相關文章!