SQL不在工作
我有两个数据库,一个包含清单,另一个包含主数据库logging的子集。
以下SQL语句不起作用:
SELECT stock.IdStock ,stock.Descr FROM [Inventory].[dbo].[Stock] stock WHERE stock.IdStock NOT IN (SELECT foreignStockId FROM [Subset].[dbo].[Products])
不在不起作用。 删除NOT会给出正确的结果,即两个数据库中的产品。 但是,使用NOT IN并不会返回任何结果。
我做错了什么,有什么想法?
SELECT foreignStockId FROM [Subset].[dbo].[Products]
可能返回一个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)
或者用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)
就像在这里看到的那样 ,你所希望的执行计划对于NOT EXISTS
来说通常是比较简单的。
行为差异的原因归结为SQL中使用的三个有价值的逻辑 。 谓词可以评估为True
, False
或Unknown
。
WHERE
子句必须计算为True
才能返回该行,但如果存在NULL
则NOT IN
不可能如下所述。
'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 Unknown
评估为Unknown
每个真值表 Unknown
”。
以下链接对各种选项的性能进行了一些额外的讨论。
- 我是否应该使用
NOT IN
,OUTER APPLY
,LEFT OUTER JOIN
,EXCEPT
或NOT EXISTS
? -
NOT IN
与NOT EXISTS
与LEFT JOIN / IS NULL
:SQL Server -
Left outer join
vsNOT EXISTS
-
NOT EXISTS
与NOT IN
如果“不在”不起作用,您可以随时尝试做“ 左连接” 。 然后使用WHEREfilter,使用连接表中的值之一( NULL值为空)进行过滤。 假设您所join的值不包含任何NULL值。