我有两个数据库,一个保存库存,另一个包含主数据库记录的子集.
以下SQL语句不起作用:
SELECT stock.IdStock
,stock.Descr
FROM [Inventory].[dbo].[Stock] stock
WHERE stock.IdStock NOT IN
(SELECT foreignStockId FROM
[Subset].[dbo].[Products])
Run Code Online (Sandbox Code Playgroud)
不是不起作用.删除NOT会得到正确的结果,即两个数据库中的产品.但是,使用NOT IN并不会返回任何结果.
我做错了什么,有什么想法吗?
Mar*_*ith 171
SELECT foreignStockId
FROM [Subset].[dbo].[Products]
Run Code Online (Sandbox Code Playgroud)
可能会返回一个NULL.
一NOT IN如有查询将不会返回任何行NULL中的列表中存在小号NOT IN值.您可以使用IS NOT NULL以下方式明确排除它们.
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)
Run Code Online (Sandbox Code Playgroud)
或者NOT EXISTS改为使用.
SELECT stock.idstock,
stock.descr
FROM [Inventory].[dbo].[Stock] stock
WHERE NOT EXISTS (SELECT *
FROM [Subset].[dbo].[Products] p
WHERE p.foreignstockid = stock.idstock)
Run Code Online (Sandbox Code Playgroud)
除了拥有您想要的语义之外,执行计划NOT EXISTS通常更简单,如此处所示.
行为差异的原因归结为SQL中使用的 三值逻辑.谓词可以计算为True,False或Unknown.
一个WHERE子句必须求值True以便返回行,但是NOT IN如果NULL存在则不可能,如下所述.
'A' NOT IN ('X','Y',NULL) 相当于 'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)
TrueTrueUnknownTrue AND True AND UnknownUnknown根据真值表评估三值逻辑.
以下链接对各种选项的性能进行了一些额外的讨论.
NOT IN,OUTER APPLY,LEFT OUTER JOIN,EXCEPT,或NOT EXISTS?NOT INvs. NOT EXISTSvs.:SQL LEFT JOIN / IS NULLServerLeft outer join VS NOT EXISTSNOT EXISTS VS NOT IN