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 joinvsNOT EXISTS -
NOT EXISTS与NOT IN
如果“不在”不起作用,您可以随时尝试做“ 左连接” 。 然后使用WHEREfilter,使用连接表中的值之一( NULL值为空)进行过滤。 假设您所join的值不包含任何NULL值。