SQL组合查询

本文讲述如何利用 UNION 操作符将多条 SELECT 语句组合成一个结果集。


1. 组合查询

多数 SQL 查询只包含从一个或多个表中返回数据的单条 SELECT 语句。但是,SQL 也允许执行多个查询(多条 SELECT 语句),并将结果作为一个查询结果集返回。这些组合查询通常称为并(union)或复合查询(compound query)。

主要有两种情况需要使用组合查询:

  • 在一个查询中从不同的表返回结构数据;
  • 对一个表执行多个查询,按一个查询返回数据。

提示: 组合查询和多个 WHERE 条件多数情况下,组合相同表的两个查询所完成的工作与具有多个 WHERE 子句条件的一个查询所完成的工作相同。换句话说,任何具有多个 WHERE 子句的 SELECT 语句都可以作为一个组合查询。


2. 创建组合查询

可用 UNION 操作符来组合数条 SQL 查询。利用 UNION,可以给出多条 SELECT 语句,将它们的结果组合成一个结果集。

2.1 使用 UNION

使用 UNION 很简单,只需给出每条 SELECT 语句,并在各条语句之间放上关键字 UNION

例子: 假如需要获取 Illinois、Indiana 和 Michigan 等美国几个州的所有顾客的报表,并包括所有的 Fun4All 顾客。可以通过 UNION 完成。

第一条查询:

sql 复制代码
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL', 'IN', 'MI');

输出结果:

sql 复制代码
cust_name       | cust_contact    | cust_email
----------------|-----------------|--------------
Village Toys    | John Smith      | sales@villagetoys.com
Fun4All         | Jim Jones       | jjones@fun4all.com
The Toy Store   | Kim Howard      | NULL

第二条查询:

sql 复制代码
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All';

输出结果:

sql 复制代码
cust_name       | cust_contact    | cust_email
----------------|-----------------|--------------
Fun4All         | Jim Jones       | jjones@fun4all.com
Fun4All         | Denise L. Stephens | dstephens@fun4all.com

组合查询:

sql 复制代码
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL', 'IN', 'MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All';

输出结果:

sql 复制代码
cust_name       | cust_contact    | cust_email
----------------|-----------------|--------------
Fun4All         | Denise L. Stephens | dstephens@fun4all.com
Fun4All         | Jim Jones       | jjones@fun4all.com
Village Toys    | John Smith      | sales@villagetoys.com
The Toy Store   | Kim Howard      | NULL

分析: 这条语句由前面的两条 SELECT 语句组成,之间用 UNION 关键字分隔。UNION 指示 DBMS 执行这两条 SELECT 语句,并把输出组合成一个查询结果集。

参考: 使用多个 WHERE 子句的查询可以如下:

sql 复制代码
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL', 'IN', 'MI') OR cust_name = 'Fun4All';

对于较复杂的过滤条件或从多个表中检索数据的情况,使用 UNION 会更加简洁。


2.2 UNION 规则

使用 UNION 时,需要注意以下规则:

  1. UNION 必须由两条或两条以上的 SELECT 语句组成,语句之间用关键字 UNION 分隔(例如,四条 SELECT 语句需要三个 UNION)。
  2. UNION 中的每个查询必须包含相同的列、表达式或聚集函数(不过,各个列的顺序不需要一致)。
  3. 列的数据类型必须兼容:类型不必完全相同,但必须是 DBMS 可以隐含转换的类型(如不同的数值类型或日期类型)。

说明: UNION 的列名。如果 SELECT 语句中的列名不同,结果集将使用第一个查询中的列名。例如,如果一条语句是 SELECT prod_name,另一条是 SELECT productname,查询结果将返回第一个列名 prod_name,而不是 productname。这意味着排序时只能使用第一个列名。


2.3 包含或取消重复的行

回到 2.1 节,我们看到的 SELECT 语句返回了重复的行。UNION 会自动去除查询结果中的重复行,这是 UNION 的默认行为。如果希望返回所有匹配的行,可以使用 UNION ALL

例子:

sql 复制代码
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL', 'IN', 'MI')
UNION ALL
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All';

输出结果:

sql 复制代码
cust_name       | cust_contact    | cust_email
----------------|-----------------|--------------
Village Toys    | John Smith      | sales@villagetoys.com
Fun4All         | Jim Jones       | jjones@fun4all.com
The Toy Store   | Kim Howard      | NULL
Fun4All         | Jim Jones       | jjones@fun4all.com
Fun4All         | Denise L. Stephens | dstephens@fun4all.com

分析: 使用 UNION ALL 时,DBMS 不会去除重复的行,因此返回了 5 行,其中有一行出现了两次。

提示: UNIONWHEREUNION 完成与多个 WHERE 条件相同的工作,但 UNION ALLUNION 的一种形式,能够返回重复的行。


2.4 对组合查询结果排序

SELECT 语句的输出可以使用 ORDER BY 子句进行排序。在 UNION 组合查询时,只能使用一条 ORDER BY 子句,并且它必须位于最后一条 SELECT 语句之后。

例子:

sql 复制代码
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL', 'IN', 'MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All'
ORDER BY cust_name, cust_contact;

输出结果:

sql 复制代码
cust_name       | cust_contact    | cust_email
----------------|-----------------|--------------
Fun4All         | Denise L. Stephens | dstephens@fun4all.com
Fun4All         | Jim Jones       | jjones@fun4all.com
The Toy Store   | Kim Howard      | NULL
Village Toys    | John Smith      | sales@villagetoys.com

说明: ORDER BY 子句位于最后一条 SELECT 语句之后,并用于对所有查询结果进行排序。


小结

本章讲解了如何使用 UNION 操作符来组合 SELECT 语句。通过 UNION,可以将多条查询的结果作为一条组合查询返回,无论结果中是否包含重复项。使用 UNION 可以简化复杂的 WHERE 子句,并且使从多个表中检索数据变得更加高效。

相关推荐
IvorySQL3 小时前
PostgreSQL 日报 | JOIN 与外键优化(8 月 9 日)
数据库·postgresql
ltl3 小时前
自治数据库十年回顾:Peloton、NoisePage、OtterTune 到云原生 auto-tuning
数据库
灯澜忆梦5 小时前
【MySQL10】进阶篇 | 索引_#2性能优化
数据库·sql·mysql·性能优化
C++ 老炮儿的技术栈7 小时前
从 Qt Designer 属性编辑器的层级可以看到继承链
c语言·数据库·c++·qt·sqlite·visual studio
MC皮蛋侠客7 小时前
Redis 系列(一):全景与最小闭环——从 `SET` 命令到内存数据结构
数据结构·数据库·redis
zt1985q8 小时前
本地部署开源网络书签与内容管理工具 Karakeep 并实现外部访问
运维·服务器·网络·数据库·网络协议·开源
IvorySQL9 小时前
PostgreSQL 日报| PostgreSQL 19 默认 WAL 压缩算法(8 月 8 日)
数据库·postgresql·区块链
油丶酸萝卜别吃9 小时前
MySQL B+ 树查询全过程详解
数据库·mysql
leisoo809710 小时前
股票数据本地化存储实战:JSON、数据库与列式存储的方案对比
jvm·数据库·json
Exclusive_Cat10 小时前
MySQL回表机制解析与优化策略
数据库·sql