T-SQL基础(四)之集合运算
三个运算符
T-SQL支持三个集合运算符:UNION、INTERSECT、EXCEPT。
集合运算符查询的一般形式如下:
Query1
<set_operator>
Query2
-- 这里,ORDER BY子句对最终结果集进行排序
[ORDER BY...]
ORDER BY
在逻辑查询处理方面,集合运算符应用于两个查询结果集,且外部的ORDER BY子句(如果有的话)应用于集合运算所得到的结果集。
每个独立的查询可以使用除了ORDER BY之外的所有逻辑查询处理阶段,原因如下:
ORDER BY会对查询结果集进行排序排序后的结果集不在表示一个集合而是游标
集合运算符只能用于集合间运算
因此,每个独立的查询语句中不能使用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运算符有两种形式:UNION、UNION 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
返回结果如下:


从上面两个结果集中可以看到,UNION与UNION ALL的区别是:UNION会去除结果集中的重复元素,而UNION ALL不会,从性能上来讲,UNION ALL优于UNION。严格来讲,UNION ALL运算结果集不能称为集合,因为集合不存在重复元素。
INTERSECT
INTERSECT用于获取两个集合的交集,分为:INTERSECT和INTERSECT 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 ALL中ALL的含义是返回所有重复行。与之类似,INTERSECT ALL中ALL的含义是不删除交集中的重复项。换个角度看,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用于获取两个集合的差集,与UNION与INTERSECT类似,EXCEPT也分为两种形式:EXCEPT和EXCEPT ALL。同样,SQL Server2014也不支持EXCEPT ALL特性。
Query1
EXCEPT
Query2
EXCEPT
与UNION、INTERSECT不同,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 ALL与EXCEPT的差异在于,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支持三个集合运算符:UNION、INTERSECT、EXCEPT,每个运算符均支持两种行为:去重(不带ALL关键字)和保留重复项(带上ALL关键字)。
T-SQL未提供对INTERSECT ALL与EXCEPT ALL的支持,我们可以通过开窗函数ROW_NUMBER()来实现。
另外需要注意一点,集合运算符认为两个NULL是相等的。
推荐阅读
T-SQL基础(四)之集合运算的更多相关文章
- SQL基础学习_06_集合运算和联结
集合运算 1. 并集:UNION 例: SELECT shohin_id, shohin_mei FROM Shohin UNION SELECT shohin_id ...
- SQL基础--查询之四--集合查询
SQL基础--查询之四--集合查询
- SQL Server中的集合运算: UNION, EXCEPT和INTERSECT
SQL Server中的集合运算包括UNION(合并),EXCEPT(差集)和INTERSECT(相交)三种. 集合运算的基本使用 1.UNION(合并两个查询结果集,隐式DINSTINCT,删除重复 ...
- SQL基础四(例子)
------------------------------------------------ --分别创建student/course/score表 Create table student ( ...
- 详解SQL集合运算
以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 ...
- SQL Server温故系列(4):SQL 查询之集合运算 & 聚合函数
1.集合运算 1.1.并集运算 UNION 1.2.差集运算 EXCEPT 1.3.交集运算 INTERSECT 1.4.集合运算小结 2.聚合函数 2.1.求行数函数 COUNT 2.2.求和函数 ...
- 集合运算 & 聚合函数
SQL 查询之集合运算 & 聚合函数 1.集合运算 1.1.并集运算 UNION 1.2.差集运算 EXCEPT 1.3.交集运算 INTERSECT 1.4.集合运算小结 2.聚合函数 ...
- [SQL] SQL 基础知识梳理(七)- 集合运算
SQL 基础知识梳理(七)- 集合运算 目录 表的加减法 联结(以列为单位) 一.表的加减法 1.集合:记录的集合(表.视图和查询的执行结果). 2.UNION(并集):表的加法 -- DDL:创建表 ...
- SQL基础教程(第2版)第7章 集合运算:7-2 联结(以列为单位对表进行联结)
第7章 集合运算:7-2 联结(以列为单位对表进行联结) ■联结的特定语法和过时语法 ● 联结( JOIN)就是将其他表中的列添加过来,进行“添加列”的集合运算.UNION是以行(纵向)为单位进行操作 ...
随机推荐
- Python3.* 和Python2.*的区别
许多Python初学者都会问:我应该学习哪个版本的Python.对于这个问题,我的回答通常是“先选择一个最适合你的Python教程,教程中使用哪个版本的Python,你就用那个版本.等学得差不多了,再 ...
- Java常见开发规范
1 背景概述 作为程序员大军中的一员,笔者工作于沈阳数通畅联软件技术有限公司.在任职工作的第一天就听领导强调开发规范的重要性,但是笔者心里还想为什么开发规范是最重要的,难道是不应该是实现功能就万事大吉 ...
- Python selenium webdriver设置js操作页面滚动条
js2 = "window.scrollTo(0,0);" #括号中为坐标 当不知道需要的滚动的坐标大小时: weizhi2 = driver.find_element_by_id ...
- 一键访问Google和YouTube等国外知名网站
1.首先打开快速安全通道网站,点击注册!网站地址 https://www.faststunnel.xyz/GWx6uy0M 2.注册好之后下载插件 3.将插件下载完后拖到浏览器安装 4.登录插件,即可 ...
- Docker学习笔记-Docker for Linux 安装
前言: 环境:centos7.5 64 位 正文: Docker 软件包已经包括在默认的 CentOS-Extras 软件源里.因此想要安装 docker,只需要运行下面的 yum 命令: yum i ...
- Python的基础语法(二)
0. 前言 接着上一篇博客的内容,我将继续介绍Python相关的语法.部分篇章可能不只是简单的语法,但是对初学者很有帮助,也建议读懂. 1. 表达式 由数字.符号.括号.变量等组成的组合. 算术表达式 ...
- python图像处理库PIL的基本概念介绍
PIL中所涉及的基本概念有如下几个:通道(bands).模式(mode).尺寸(size).坐标系统(coordinate system).调色板(palette).信息(info)和滤波器(filt ...
- Kibana简单使用教程
ELK平台日志查看教程 1. 访问地址:http://xxx:5601/app/kibana 我们主要使用的是右边Discover功能,默认显示的是183tpp(可设置)最近15分钟日志信息. 2. ...
- mysql 开发进阶篇系列 14 锁问题(避免死锁,死锁查看分析)
一. 概述 通常来说,死锁都是应用设计问题,通过调整业务流程,数据库对象设计,事务大小,以及访问数据库的sql语句,绝大部分死锁都可以避免,下面介绍几种避免死锁的常用 方法. 1. 在应用中,如果不同 ...
- Selenuim自动化测试模型
本章内容: 概念介绍 自动化测试模型 一.概念 自动化测试库.框架.工具之间的区别: 库是由代码集合成的一个产品,供程序员调用,面向对象的代码组织形成的库叫类库,面向过程的代码组织形成的库叫函数库. ...

