EXCEPT 运算符与 NOT IN

Hei*_*erg 18 sql-server-2005 sql-server sql-server-2008-r2 operator except

EXCEPT运营商已在SQL Server 2005中引入的,但之间有什么区别NOT INEXCEPT

它也这样做吗?我想用一个例子做一个简单的解释。

Mar*_*son 32

EXCEPT和之间有两个主要区别NOT IN

除了

EXCEPT过滤DISTINCT左侧表中未出现在右侧表中的值。它本质上与执行NOT EXISTSwithDISTINCT子句相同。

它还期望两个表(或表中列的子集)在查询的左侧和右侧具有相同数量的列

例如,您不能这样做:

SELECT ID, Name FROM TableA
EXCEPT
SELECT ID FROM TableB
Run Code Online (Sandbox Code Playgroud)

这将导致错误:

使用 UNION、INTERSECT 或 EXCEPT 运算符组合的所有查询在其目标列表中必须具有相同数量的表达式。

不在

NOT IN不过滤DISTINCT值并返回左侧表中未出现在右侧表中的所有值。

NOT IN 要求您将一个表中的单个列与另一个表或子查询中的单个列进行比较。

例如,如果您的子查询要返回多列:

SELECT * FROM TableA AS nc
WHERE ID NOT IN (SELECT ID, Name FROM TableB AS ec)
Run Code Online (Sandbox Code Playgroud)

你会得到以下错误:

当子查询未通过 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)
Run Code Online (Sandbox Code Playgroud)

从上面的两个查询中,EXCEPT从 返回 3 行#NewCustomers,过滤掉匹配的 1 和 3#ExistingCustomers以及重复的 8。

NOT IN不进行这种不同的过滤,并从#NewCustomers重复的 8 中返回 4 行。

如果我们现在将 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;
Run Code Online (Sandbox Code Playgroud)

取而代之的是NOT IN,您应该真正查看Gail Shaw 的博客NOT EXISTS上的两者之间的很好的比较。