组合查询
组合查询具有两个或多个 SELECT 语句,由负责结合两个查询的操作符组成。本节介绍如何使用操作符 union、intersect、minus 把多个 SQL 查询组合为一个。
使用规则:在使用组合查询操作符时,每个 SELECT 语句里必须选择同样数量的字段、同样数量的字段表达式、同样的数据类型、同样的次序——但长度不必一样。
本节的例子使用的是 learnsql 数据库里的雇员表、雇员工资表、顾客信息表和订单表。
一、并集 union
1、union
union 操作符可以组合两个或多个 SELECT 语句的结果,不包含重复的记录。如果某行的输出存在于一个查询结果里,其他查询结果同一行的记录就不会再输出了。
语法:
SELECT 列名
FROM 表名
[ WHERE . . . ]
UNION
SELECT 列名
FROM 表名
[ WHERE . . . ]
例1:查询雇员 ID:
SELECT EMP_ID FROM EMPLOYEE_TBL;
结果:
EMP_ID
213764555
220984332
311549902
313782439
442346889
443679012
在 EMPLOYEE_TBL 表里 EMP_ID 有6行记录。
SELECT EMP_ID FROM EMPLOYEE_PAY_TBL;
结果:
EMP_ID
442346889
443679012
313782439
213764555
311549902
在 EMPLOYEE_PAY_TBL 表里 EMP_ID 有5行记录。
SELECT EMP_ID FROM EMPLOYEE_TBL
UNION
SELECT EMP_ID FROM EMPLOYEE_PAY_TBL;
结果:
EMP_ID
213764555
220984332
311549902
313782439
442346889
443679012
雇员 ID 在两个表里都存在,但在结果里只出现一次。
2、union all
union all 操作符可以组合两个 SELECT 语句的结果,并且包含重复的结果。它与 union 基本上是一样的,只是一个返回重复的结果,一个不返回。
语法:
SELECT 列名
FROM 表名
[ WHERE . . . ]
UNION ALL
SELECT 列名
FROM 表名
[ WHERE . . . ]
例2:下面这个语句返回全部雇员 ID,并且包含重复的记录:
SELECT EMP_ID FROM EMPLOYEE_TBL
UNION ALL
SELECT EMP_ID FROM EMPLOYEE_PAY_TBL;
结果:
EMP_ID
213764555
220984332
311549902
313782439
442346889
443679012
442346889
443679012
313782439
213764555
311549902
因为 union all 操作符会返回重复的数据,所以这个查询返回了11条记录。
二、交集 intersect
intersect 可以组合两个 SELECT 语句,但只返回两个语句里一样的记录。
语法:
SELECT 列名
FROM 表名
[ WHERE . . . ]
INTERSECT
SELECT 列名
FROM 表名
[ WHERE . . . ]
例3:查询具有订单的顾客的 ID:
SELECT CUST_ID FROM CUSTOMER_TBL;
结果:
CUST_ID
090
109
12
21
221
232
287
288
333
345
43
432
560
590
610
715
返回16条记录。
SELECT CUST_ID FROM ORDERS_TBL;
结果:
CUST_ID
090
12
232
287
43
432
返回6条记录。
SELECT CUST_ID FROM CUSTOMER_TBL
INTERSECT
SELECT CUST_ID FROM ORDERS_TBL;
结果:
CUST_ID
090
12
232
287
43
432
返回两表里相同的6条记录。
三、差集 minus
MINUS 操作符组合两个 SELECT 语句,返回第一个语句里有但第二个语句里没有的记录。
语法:
SELECT 列名
FROM 表名
[ WHERE . . . ]
MINUS
SELECT 列名
FROM 表名
[ WHERE . . . ]
例4:查询没有订单的顾客的 ID:
SELECT CUST_ID FROM CUSTOMER_TBL
MINUS
SELECT CUST_ID FROM ORDERS_TBL;
结果:
CUST_ID
109
21
221
288
333
345
560
590
610
715
返回第一个表里有但第二个表里没有的10条记录。
四、小结
组合查询可以让多个查询一起返回一个统一的数据集。本节介绍的组合操作符包括 union、union all、intersect 和 minus。union 返回两个查询的全部结果,不管数据是否重复。intersect 返回两个查询结果中一样的记录。minus 返回一个查询结果中不存在于另一个查询结果的记录。组合查询具有很大的灵活性,能够满足各种查询的要求。如果不使用组合查询,可能需要很复杂的查询语句才能达到同样的结果。
使用组合查询时要小心。在使用 intersect 操作符时,如果第一个查询的 SELECT 语句有问题,就可能会得到不正确或不完整的数据。在使用 union 和union all 操作符时,要考虑是否需要返回重复的数据。而使用 minus 操作符时,我们要考虑是否需要不存在于第二个查询里的数据。组合查询里的错误组合操作符或单个查询的次序有误都会导致返回不正确的数据。
如果两个查询语句的字段名不同,第一个查询决定了输出的字段名称。
另外,MySQL 不支持 INTERSECT 和 MINUS,使用时要加以注意,可以使用其它替代方法。
【参考资料】
W3SChool 在线SQL教程 http://www.w3SChool.com.cn/sql/sql_union.asp SQL UNION 和 UNION ALL 操作符
课后练习:
1. 匹配操作符与相应的描述:
描述 操作符
a. 显示重复记录 union
b. 返回第一个查询里有但第二个查询里没有的结果 intersect
c. 返回不重复的记录 union all
d. 返回第一个查询里与第二个查询匹配的结果 minus
2. 使用数据库 learnsql 里的表 CUSTOMER_TBL 和 ORDERS_TBL 编写组合查询:
1)返回下了订单的顾客。
2)返回没有下订单的顾客。