SQL NOT IN不工作

Sam*_*Sam 70 sql sql-server

我有两个数据库,一个保存库存,另一个包含主数据库记录的子集.

以下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,FalseUnknown.

一个WHERE子句必须求值True以便返回行,但是NOT IN如果NULL存在则不可能,如下所述.

'A' NOT IN ('X','Y',NULL) 相当于 'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)

  • 'A'<>'X'= True
  • 'A'<>'Y'= True
  • 'A'<> NULL = Unknown

True AND True AND UnknownUnknown根据真值表评估三值逻辑.

以下链接对各种选项的性能进行了一些额外的讨论.