首页 > 代码库 > EXCEPT(差集)集合运算
EXCEPT(差集)集合运算
在集合论中,集合A与B的差集(A-B)是由属于集合A,但不属于集合B的元素组成的集合。可以认为两个集合的差A-B就是从A中减去B中也属于A的元素。
在T-SQL中,集合之差是用EXCEPT集合运算实现的。EXCEPT运算对两个输入查询的结果集进行操作,返回出现在第一个结果集中,但不出现在第二个结果集中的所有行。
EXCEPT DISTINCT 集合运算
EXCEPT 集合运算在逻辑上先删除两个输入多集中的重复行(把多集转变成集合),然后返回只在第一个集合中出现,在第二个集合中不出现所有行。换句话说,一个行能够被返回,仅当这个行在第一个输入的多集中至少出现一次,而且在第二个多集中没有出现过。
注意:EXCEPT 运算与其他两种集合运算不同,EXCEPT 是不对称的。亦即,对于其他两种集合运算,哪个输入查询放在前面,哪个输入查询放在后面是无关紧要的;但EXCEPT 集合运算就不是这样了。
SELECT country FROM dbo.Employees
EXCEPT
SELECT country FROM dbo.Customers
EXCEPT 运算也可以用其他方法来实现。一种方法是使用外联接,筛选出在联接左边出现而在右边不出现的外部行。另一种方法是使用 NOT EXISTS 谓词。
EXCEPT ALL集合运算
EXCEPT ALL 运算与EXCEPT运算非常类似,但它还考虑了每一行的出现次数。假设行R在第一个多集中出现了x次,在第二个多集中出现y次,且x>y,则在Query1 EXCEPT ALL Query2中,R出现 x-y次。换句话说,如果一个行在第一个多集中出现了多次,EXCEPT ALL 逻辑上只返回它在第二个多集中没有相应出现过的那些行。虽然 SQL Server 没有提供内建的EXCEPT ALL 运算,但用与INTERSECT ALL的解决方案类似的方法,也可以为EXCEPT ALL 提供替代的解决方案。也就是为每个输入查询增加一个ROW_Number计算,算出每行是第几次出现,再对两个输入集应用EXCEPT 运算。这样就只返回出现次数找不到匹配的行。
SELECT ROW_NUMBER() over(partition by country,region order by (SELECT 0)) as rownum,country
FROM dbo.Employees
EXCEPT
SELECT ROW_NUMBER() over(PARTITION BY country,region order by (SELECT 0)),country
FROM dbo.Customers