SELECT * FROM TableA AS nc
WHERE ID NOT IN (SELECT ID, Name FROM TableB AS ec)
您会收到以下错误:
当不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式。
但是,如果右侧表NULL在被 过滤的值中包含 a,NOT IN则返回空结果集,可能会产生意外结果。
例子
CREATE TABLE #NewCustomers (ID INT);
CREATE TABLE #ExistingCustomers (ID INT);
INSERT INTO #NewCustomers
( ID )
VALUES
(8), (9), (10), (1), (3), (8);
INSERT INTO #ExistingCustomers
( ID )
VALUES
( 1) , (2), (3), (4), (5);
-- EXCEPT filters for DISTINCT values
SELECT * FROM #NewCustomers AS nc
EXCEPT
SELECT * FROM #ExistingCustomers AS ec
-- NOT IN returns all values without filtering
SELECT * FROM #NewCustomers AS nc
WHERE ID NOT IN (SELECT ID FROM #ExistingCustomers AS ec)
如果我们现在将 a 添加NULL到#ExistingCustomers表中,我们会看到由 返回的相同结果EXCEPT,但是NOT IN将返回一个空结果集。
INSERT INTO #ExistingCustomers
( ID )
VALUES
( NULL );
-- With NULL values in the right-hand table, EXCEPT still returns the same results as above
SELECT * FROM #NewCustomers AS nc
EXCEPT
SELECT * FROM #ExistingCustomers AS ec
-- NOT IN now returns no results
SELECT * FROM #NewCustomers AS nc
WHERE ID NOT IN (SELECT ID FROM #ExistingCustomers AS ec)
DROP TABLE #NewCustomers;
DROP TABLE #ExistingCustomers;
EXCEPT
和之间有两个主要区别NOT IN
。除了
EXCEPT
过滤DISTINCT
左侧表格中未出现在右侧表格中的值。NOT EXISTS
它与使用DISTINCT
子句基本相同。它还期望两个表(或表中列的子集)在查询的左侧和右侧具有相同数量的列
例如,您不能这样做:
这将导致错误:
不在
NOT IN
不过滤DISTINCT
值并返回左侧表中未出现在右侧表中的所有值。NOT IN
要求您将一个表中的单个列与另一个表或子查询中的单个列进行比较。例如,如果您的子查询要返回多个列:
您会收到以下错误:
但是,如果右侧表
NULL
在被 过滤的值中包含 a,NOT IN
则返回空结果集,可能会产生意外结果。例子
从上面的两个查询中,
EXCEPT
返回 3 行#NewCustomers
,过滤掉匹配的 1 和 3#ExistingCustomers
以及重复的 8。NOT IN
不执行此不同的过滤并从#NewCustomers
重复的 8 中返回 4 行。如果我们现在将 a 添加
NULL
到#ExistingCustomers
表中,我们会看到由 返回的相同结果EXCEPT
,但是NOT IN
将返回一个空结果集。取而代之的是
NOT IN
,您应该真正查看Gail Shaw 的博客NOT EXISTS
上的两者之间的一个很好的比较。马克辛金森出色评论的补充:
实际上,您可以
NOT IN
使用多个列执行。例如,这是一个完全合法的* SQL 查询:
这将返回所有员工,但不是经理
first_name
。last_name
*:但在 SQL Server 中尚未实现构造。
上面的 NOT IN 失败,因为需要在主查询和子查询中的谓词之间存在关联。如果你忽略它,你会得到一个 UNCORRELATED 子查询。
SELECT * FROM TableA AS nc WHERE ID NOT IN (SELECT ID, Name FROM TableB AS ec where nc.ID = ec.ID)
EXCEPT 更好,可以在不使用 IS NULL / IS NOT NULL 谓词的情况下处理任何空行。