了解集合运算(如UNION、INTERSECT、EXCEPT)的概念和应用场景,能够将多个查询结果进行合并、交集和差集运算

本文章为 SQL Server 的详细学习大纲 里面的一个子章节的详细介绍,如果想了解相关的其他内容,可以从这里面查看,或者查看SQL Server专栏,里面有些文章可能并不在 SQL Server 的详细学习大纲 里面,以及一些补充内容。

一、简单介绍

  • 有时候希望对查询的多个结果集做合并、交集、差集运算。SQL Server 提供了多个集运算符来给我们进行运算,以下是对各个集运算符做一些简单的介绍。
    • UNION 合并两个或多个 SELECT 语句的结果集,去掉重复的行。
    • UNION ALL 合并两个或多个 SELECT 语句的结果集,不去掉重复的行。
    • INTERSECT 返回两个或多个 SELECT 语句结果集的交集。
    • EXCEPT 返回在第一个 SELECT 语句结果集中存在,但在第二个 SELECT 语句结果集中不存在的行。
  • 注意点
    • 多个 SELECT 语句的结果集的列定义不一定要相同,但必须可通过隐式转换实现兼容。 如果数据类型不同,则根据数据类型优先级规则确定所产生的数据类型。 如果类型相同,但精度、确定位数或长度不同,那么结果以相同的表达式合并规则为依据。
    • 返回的列名显示的是第一个结果集的列名称,如果后面要使用ORDER BY ,要使用第一个结果集的列名,否则会报错

二、构建测试数据

-- 创建表TableA
CREATE TABLE TableA (
    ID INT,
    AName VARCHAR(50)
);

-- 创建表TableB
CREATE TABLE TableB (
    ID INT,
    BName VARCHAR(50)
);

-- 向TableA插入数据
INSERT INTO TableA (ID, AName) VALUES
(1, 'Alice'),
(2, 'Bob'),
(3, 'Charlie');

-- 向TableB插入数据
INSERT INTO TableB (ID, BName) VALUES
(2, 'Bob'),
(3, 'Charlie'),
(4, 'David');
select * from TableA;
select * from TableB;

结果:
在这里插入图片描述

三、UNION与UNION ALL

  • 两个结果集代码演示

-- 使用UNION合并TableA和TableB的数据,去除重复行,列名显示第一个结果集
SELECT ID, AName FROM TableA
UNION
SELECT ID, BName FROM TableB
;
-- 使用UNION ALL合并TableA和TableB的数据,不去除重复行,列名显示第一个结果集
SELECT ID, AName FROM TableA
UNION ALL
SELECT ID, BName FROM TableB
;
  • 结果:
    在这里插入图片描述
    返回的列名显示的是第一个结果集的列名称

  • 多个结果集演示

SELECT ID, AName FROM TableA
UNION ALL
SELECT ID, BName FROM TableB
UNION ALL
SELECT ID, BName FROM TableB
……

四、INTERSECT与EXCEPT

  • 代码演示
-- 交集,TableA与TableB均有的数据,列名显示第一个结果集
SELECT ID, AName FROM TableA
INTERSECT
SELECT ID, BName FROM TableB
;
-- 差集,TableA去掉在TableB存在的数据行
SELECT ID, AName FROM TableA
EXCEPT
SELECT ID, BName FROM TableB
;
  • 结果
    在这里插入图片描述

五、ORDER BY 与集合操作符

  • 几个常见的错误
    • 位置问题,不在操作结果集的最后面
    • 在结果集的最后面,但用的列不是第一个结果集的列

示例一:

SELECT ID, AName FROM TableA
ORDER BY AName
UNION
SELECT ID, BName FROM TableB

结果:
在这里插入图片描述
示例二:

SELECT ID, AName FROM TableA
UNION
SELECT ID, BName FROM TableB
ORDER BY BName
;

结果:
在这里插入图片描述
原因是因为ORDER BY 只能操作集运算之后的结果,不能进行操作子集,即使你把子集合用()包起来
示例三:

SELECT ID, AName FROM TableA
UNION ALL
select * from(
SELECT ID, BName FROM TableB
ORDER BY BName) B
;

结果:
在这里插入图片描述

六、WHERE与集合操作符使用

WHERE与ORDER BY 不一样,这个是对子集合进行操作的,不是对结果进行操作的,以下是两个语句的示例:

-- 对的,WHERE语句是对子集TableB的操作,过滤之后再进行合并操作
SELECT ID, AName FROM TableA
UNION
SELECT ID, BName FROM TableB
WHERE BName ='Bob'
;

-- 错的,WHERE语句是对子集TableB的操作,TableB没有列名为AName的列,会报错
SELECT ID, AName FROM TableA
UNION
SELECT ID, BName FROM TableB
WHERE AName ='Bob'
;
  • 对结果集运算的结果进行过滤可以使用子查询,如:
SELECT * FROM (
	SELECT ID, AName FROM TableA
	UNION
	SELECT ID, BName FROM TableB
) A
WHERE AName ='Bob'
;

结果:
在这里插入图片描述

七、SELECT INTO 与集运算符使用

SELECT INTO 与ORDER BY 一样,都是对结果集进行操作的,也就是合并、交集、差集之后的结果,再进行INTO操作。

SELECT ID, AName INTO TEST FROM TableA
EXCEPT
SELECT ID, BName FROM TableB
;
SELECT * FROM TEST

结果:
在这里插入图片描述

八、结尾

这几个集运算符除了运算的逻辑不一样外,其他的操作逻辑都是一样的,所以这里合并在一起进行说明,例子也只进行对一个集运算符进行说明,其实其他的几个也是一样的。原理都是一样的,我们要学会扩展思维,也可以自己多进行验证,只要弄懂了一个,其他的基本也懂了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

生命不息-学无止境

你的每一份支持都是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值