T-SQL基础(四)之集合运算

三个运算符

T-SQL支持三个集合运算符:UNION、INTERSECT、EXCEPT。

集合运算符查询的一般形式如下:

Query1
<set_operator>
Query2
-- 这里,ORDER BY子句对最终结果集进行排序
[ORDER BY...]

ORDER BY

在逻辑查询处理方面,集合运算符应用于两个查询结果集,且外部的ORDER BY子句(如果有的话)应用于集合运算所得到的结果集

每个独立的查询可以使用除了ORDER BY之外的所有逻辑查询处理阶段,原因如下:

  1. ORDER BY会对查询结果集进行排序
  2. 排序后的结果集不在表示一个集合而是游标
  3. 集合运算符只能用于集合间运算

因此,每个独立的查询语句中不能使用ORDER BY子句

其它查询逻辑

对集合运算结果集使用除ORDER BY之外的查询逻辑则易引发逻辑错误:

USE WJChi;
?
SELECT Name AS 姓名,Age FROM dbo.UserInfo AS U1
UNION ALL
SELECT Name,Age AS 年龄 FROM dbo.UserInfo AS U2
WHERE Age>26;
?
-- 上述写法等价于(注意WHERE条件)
SELECT Name AS 姓名,Age FROM dbo.UserInfo AS U1
UNION ALL
SELECT Name,Age AS 年龄 FROM dbo.UserInfo AS U2
WHERE U2.Age>26;

可以借助表表达式对集合运算符运算结果集使用ORDER BY之外的查询逻辑:

USE WJChi;
?
SELECT * FROM
(
    SELECT Name AS 姓名,Age FROM dbo.UserInfo AS U1
    UNION ALL
    SELECT Name,Age AS 年龄 FROM dbo.UserInfo AS U2
) AS T
WHERE T.Age>26;

上述查询也可使用派生表之外的表表达式,如:CTE。

集合的列

用于集合运算符的两个查询必须返回相同列数且对应列数据类型相互兼容的结果集。在进行比较运算时,集合运算符会认为两个NULL值是相等的

集合运算符返回结果集中的列名是第一个查询中的列名:

USE WJChi;
?
SELECT Name AS 姓名,Age FROM dbo.UserInfo AS U1
UNION
SELECT Name,Age AS 年龄 FROM dbo.UserInfo AS U2
ORDER BY Age

返回结果如下:

UNION

UNION用于获取两个集合的并集。

UNION运算符有两种形式:UNIONUNION ALL

UNION

USE WJChi;
?
SELECT Name AS 姓名,Age FROM dbo.UserInfo AS U1
UNION
SELECT Name,Age AS 年龄 FROM dbo.UserInfo AS U2
ORDER BY Age

返回结果如下:

UNION ALL

USE WJChi;
?
SELECT Name AS 姓名,Age FROM dbo.UserInfo AS U1
UNION ALL
SELECT Name,Age AS 年龄 FROM dbo.UserInfo AS U2
ORDER BY Age

返回结果如下:

从上面两个结果集中可以看到,UNIONUNION ALL的区别是:UNION会去除结果集中的重复元素,而UNION ALL不会,从性能上来讲,UNION ALL优于UNION。严格来讲,UNION ALL运算结果集不能称为集合,因为集合不存在重复元素。

INTERSECT

INTERSECT用于获取两个集合的交集,分为:INTERSECTINTERSECT ALL两种形式,二者区别同UNION运算符。

INTERSECT

可以使用内联接或者EXSITS谓词来替代INTERSECT,但在比较运算时,INTERSECT将两个NULL值视为相等,而替代方案不会。

INTERSECT只关注行的内容是否相同,不关注行出现的次数:

USE WJChi;
?
SELECT Name AS 姓名,Age FROM dbo.UserInfo AS U1
INTERSECT
SELECT Name,Age AS 年龄 FROM dbo.UserInfo AS U2
ORDER BY Age;

INTERSECT ALL

SQL标准中包含INTERSECT ALL,但在SQL Server2014中未实现该特性,在SQL Server2014中使用INTERSECT ALL会报错:

不支持 INTERSECT 运算符的 ‘ALL‘ 版本。

UNION ALLALL的含义是返回所有重复行。与之类似,INTERSECT ALLALL的含义是不删除交集中的重复项。换个角度看,INTERSECT ALL不仅关心两侧存在的行,还关心每一侧行出现的次数,即:

如果某一数据在第一个输入中出现了a次,在第二个输入中出现了b次,那么在运算结果中该行出现min(a,b)次

下面,我们借助开窗函数ROW_NUMBER()实现了INTERSECT ALL的效果:

USE WJChi;
?
SELECT
ROW_NUMBER() OVER(PARTITION BY Name,Age ORDER BY Age) AS RowNumber,
Name,Age
FROM dbo.UserInfo;

经过开窗函数ROW_NUMBER()的处理后,原本相同的数据被视为不同。

USE WJChi;
?
-- 实现INTERSECT ALL效果
SELECT T.Name,T.Age FROM
(
    SELECT
    ROW_NUMBER() OVER(PARTITION BY Name,Age ORDER BY Age) AS RowNumber,
    Name,Age
    FROM dbo.UserInfo

    INTERSECT

    SELECT
    ROW_NUMBER() OVER(PARTITION BY Name,Age ORDER BY Age) AS RowNumber,
    Name,Age
    FROM dbo.UserInfo
) AS T
ORDER BY T.Age;

查询结果如下:

EXCEPT

EXCEPT用于获取两个集合的差集,与UNIONINTERSECT类似,EXCEPT也分为两种形式:EXCEPTEXCEPT ALL。同样,SQL Server2014也不支持EXCEPT ALL特性。

Query1
EXCEPT
Query2

EXCEPT

UNIONINTERSECT不同,EXCEPT运算符对于两个查询的先后顺序有要求:EXCEPT返回存在于Query1中出现且不在Query2中出现的行,EXCEPT只关注行是否重复,而不关注行出现的次数。

可以使用外联接或者NOT EXISTS来替代EXCEPT,但在比较运算时,EXCEPT将两个NULL值视为相等,而替代方案不会。

准备如下数据:

USE WJChi;
?
SELECT Name,Age FROM #temp;
SELECT Name,Age FROM dbo.UserInfo;

那么,下面两条SQL的运算结果集均不包含任何数据:

SELECT Name ,Age FROM #temp
EXCEPT
SELECT Name,Age FROM dbo.UserInfo
ORDER BY Age;
?
SELECT Name ,Age FROM dbo.UserInfo
EXCEPT
SELECT Name,Age FROM #temp
ORDER BY Age;

EXCEPT ALL

EXCEPT ALLEXCEPT的差异在于,EXCEPT ALL不止考虑行是否重复,还会考虑行出现的次数:

如果某一数据在第一个输入中出现了a次,在第二个输入中出现了b次,那么在运算结果中该行出现a-b次。若a<b则运算结果中不包含该行。

同样,我们借助开窗函数ROW_NUMBER()来实现EXCEPT ALL效果:

USE WJChi;
?
SELECT
T.Name,T.Age
FROM
(
    SELECT
    ROW_NUMBER() OVER(PARTITION BY Name,Age ORDER BY Age) AS RowNumber,
    Name,Age
    FROM #temp

    EXCEPT

    SELECT
    ROW_NUMBER() OVER(PARTITION BY Name,Age ORDER BY Age) AS RowNumber,
    Name,Age
    FROM dbo.UserInfo
) AS T
ORDER BY T.Age;

小结

标准SQL支持三个集合运算符:UNIONINTERSECTEXCEPT,每个运算符均支持两种行为:去重(不带ALL关键字)和保留重复项(带上ALL关键字)。

T-SQL未提供对INTERSECT ALLEXCEPT ALL的支持,我们可以通过开窗函数ROW_NUMBER()来实现。

另外需要注意一点,集合运算符认为两个NULL是相等的。

推荐阅读

T-SQL基础(三)之子查询与表表达式

原文地址:https://www.cnblogs.com/Cwj-XFH/p/10035453.html

时间: 2024-11-09 10:15:17

T-SQL基础(四)之集合运算的相关文章

SQL基础学习_06_集合运算和联结

集合运算 1. 并集:UNION ? ? 例: ? ? SELECT shohin_id, shohin_mei? ? FROM Shohin? ? UNION? ? SELECT shohin_id, shohin_mei? ? FROM Shohin2; ? ? 将Shohin和Shohin2两张表的shohin_id和shohin_mei两列取并集: ? ? 注意,UNION操作时,列数必须相等,且每列的数据类型应该相同 ? ? 保留重复行: UNION ALL 2. 交集:INTERSE

Sql学习笔记3——集合运算、空值和聚集函数

1.集合运算 SQL作用在关系上的union.intersect和except(Oracle中用minus代替except)运算,对应于数学集合论中的并.交和差运算.这三个运算都自动去除重复. eg: 找出在2009年秋季学期开课但不在2010年春季开课的所有课程 (select course_id from section where semester=‘Fall’ and year=2009) except (select course_id from section where semes

sql基础语句大集合

每次都习惯于使用SQL Sever直接设计数据库,而没有把对SQL语句引起足够的重视,借这次机房合作版重构的机会,使用SQL语句来一次数据库设计,同时对SQL语句的基本用法做一下梳理. [分类] SQL语句有9种,按照功能划分类别可大体分为4种: 1.查询语句:select ----数据库中最常用用的语句 2.数据定义:create,drop,alter----针对数据库和数据表以及表中的字段进行的操作 3.数据操纵:insert,update,delete----传说中的"增删改查"

SQL基础四

INSERT INTO<表明>(列名1,列名2,.....,列名n) VALUES(列表表达式1,列表表达式2,.....,列表表达式n); UPDATE<表名> SET<列名1>=<列表表达式1> <列表2>=<列表表达式2> ,...... ,....<列表n>=<列表表达式n> WHERE<条件字句> SELECT<列表1,列表2,....,列表n> FROM <表名>

详解SQL集合运算

以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础]04.表表达式-上篇 [T-SQL基础]04.表表达式-下篇 [T-SQL基础]05.集合运算 [T-SQL基础]06.透视.逆透视.分组集 [T-SQL基础]07.数据修改 [T-SQL基础]08.事务和并发 [

SQL集合运算

转载:详解SQL集合运算 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础]04.表表达式-上篇 [T-SQL基础]04.表表达式-下篇 [T-SQL基础]05.集合运算

集合运算 &amp; 聚合函数

1.集合运算 1.1.并集运算 UNION 1.2.差集运算 EXCEPT 1.3.交集运算 INTERSECT 1.4.集合运算小结 2.聚合函数 2.1.求行数函数 COUNT 2.2.求和函数 SUM 2.3.求最大值函数 MAX 2.4.求最小值函数 MIN 2.5.求平均值函数 AVG 2.6.聚合函数小结 3.本文小结 1.集合运算 在数学中,不仅可以对指定的数字个体做四则运算,还可以对指定的集合整体做交并补运算.类似的,在数据库中也是不仅可以对具体的数据行进行增删改查,还可以对查询

[SQL] SQL 基础知识梳理(七)- 集合运算

SQL 基础知识梳理(七)- 集合运算 目录 表的加减法 联结(以列为单位) 一.表的加减法 1.集合:记录的集合(表.视图和查询的执行结果). 2.UNION(并集):表的加法 -- DDL:创建表 CREATE TABLE Shohin2 (shohin_id CHAR(4) NOT NULL, shohin_mei VARCHAR(100) NOT NULL, shohin_bunrui VARCHAR(32) NOT NULL, hanbai_tanka INTEGER , shiire

笔记-Microsoft SQL Server 2008技术内幕:T-SQL语言基础-06 集合运算

T-SQL支持3种集合运算:并集(UNION).交集(INTERSECT)和差集(EXCEPT).集合运算涉及的两个查询不能包含ORDER BY子句. UNION ALL集合运算 UNION ALL不会对行进行比较,也不会删除重复行.假设查询Query1返回m行,查询Query2返回n行,则Query1 UNION ALL Query2返回(m+n)行. SELECT country, region, city FROM HR.Employees UNION ALL SELECT country