T-SQL支持3种集合运算:并集(UNION)、交集(INTERSECT)和差集(EXCEPT)。集合运算涉及的两个查询不能包含ORDER BY子句。函数
UNION ALL不会对行进行比较,也不会删除重复行。假设查询Query1返回m行,查询Query2返回n行,则Query1 UNION ALL Query2返回(m+n)行。spa
SELECT country, region, city FROM HR.Employees UNION ALL SELECT country, region, city FROM Sales.Customers;
UNION DISTINCT会删除重复行。code
SELECT country, region, city FROM HR.Employees UNION SELECT country, region, city FROM Sales.Customers;
SELECT country, region, city FROM HR.Employees INTERSECT SELECT country, region, city FROM Sales.Customers;
注意一点,集合运算对行进行比较时,认为两个NULL值相等。blog
SQL Server不支持内建的INTERSECT ALL运算,须要用替代的解决方案来实现INTERSECT ALL。能够用ROW_NUMBER来实现此需求。排序
SELECT ROW_NUMBER() OVER(PARTITION BY country, region, city ORDER BY (SELECT 0)) AS rownum, country, region, city FROM HR.Employees INTERSECT SELECT ROW_NUMBER() OVER(PARTITION BY country, region, city ORDER BY (SELECT 0)), country, region, city FROM Sales.Customers;
执行结果:ci
注意上面的SQL中,在排序函数的OVER子句中使用ORDER BY(SELECT<常量>)是告诉SQL Server没必要在乎行的顺序。若是想让返回的结果不包含行号,则能够在这个查询基础上定义一个表表达式,如:it
WITH INTERSECT_ALL AS ( SELECT ROW_NUMBER() OVER(PARTITION BY country, region, city ORDER BY (SELECT 0)) AS rownum, country, region, city FROM HR.Employees INTERSECT SELECT ROW_NUMBER() OVER(PARTITION BY country, region, city ORDER BY (SELECT 0)), country, region, city FROM Sales.Customers ) SELECT country, region, city FROM INTERSECT_ALL;
SELECT country, region, city FROM HR.Employees EXCEPT SELECT country, region, city FROM Sales.Customers;
注意,在EXCEPT集合运算中,交换两个集合的运算位置会使运算结果不一样。io
WITH EXCEPT_ALL AS ( SELECT ROW_NUMBER() OVER(PARTITION BY country, region, city ORDER BY (SELECT 0)) AS rownum, country, region, city FROM HR.Employees EXCEPT SELECT ROW_NUMBER() OVER(PARTITION BY country, region, city ORDER BY (SELECT 0)), country, region, city FROM Sales.Customers ) SELECT country, region, city FROM EXCEPT_ALL;