对 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中文网其他相关文章!