开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 28 天,点击查看活动详情
本节主要记录了如何使用 UNION 操作符将多条 SELECT 语句组合成一个结果集。
组合查询
大多数 SQL 查询都是只包含了单条 SELECT 语句。现在,我们还可以使用 UNION 操作符来组合多条 SQL 查询,让 MySQL 执行多条 SELECT 语句,并将结果作为单个查询结果集返回。
这种多条 SELECT 语句组合查询的情况通常被称为并(union)查询 或者 复合(compound)查询。
组合查询和多个
WHERE条件:
- 多数情况下,组合相同表的两个查询完成的工作与具有多个
WHERE子句条件的单条查询完成的工作相同。- 换句话说,任何具有多个
WHERE子句的SELECT语句都可以作为一个组合查询给出。
创建组合查询
使用 UNION
先来看两个例子:
- 检索价格小于等于 100 的所有产品:
select
vend_id, prod_id, prod_price
from
products
where
prod_price <= 100;
- 检索 供应商ID 为 1001 和 1009 生产的所有物品:
select
vend_id, prod_id, prod_price
from
products
where
vend_id in (1001, 1009);
- 现在,我们使用
UNION操作符来组合这两条SQL查询:
select
vend_id, prod_id, prod_price
from
products
where
prod_price <= 100
union
select
vend_id, prod_id, prod_price
from
products
where
vend_id in (1001, 1009);
记录:
- 可以看到,
UNION操作符将两条SELECT语句组合在一起,其中,两条语句用UNION关键字分隔。 - 也就是说,
UNION操作符指示 MySQL 执行两条SELECT语句,并将输出组合成单个查询结果集。
另一方面,我们也意识到,这个组合查询可以使用多条 where 子句进行代替,如下所示:
select
vend_id, prod_id, prod_price
from
products
where
prod_price <= 100 or vend_id in (1001, 1009);
事实上,无论是组合查询还是使用多个
WHERE条件,都是可行的。这两种技术在不同的查询中性能也不同。对于复杂的过滤条件或者从多个表中检索数据的情况时,使用组合查询可能会使处理更简单。
注意事项
在使用组合查询时(UNION),注意事项如下:
union操作符必须由两条或两条以上的select语句组成,语句之间用关键字union进行分隔(组合 3 条select语句将要使用 2 个union操作符)union组合的每个查询语句必须包含相同的列、表达式或聚集函数(次序不要求)- 列数据必须兼容,数据类型不必完全相同,但是必须是 MySQL 中可以隐含地转换的类型。
- 在使用
union进行组合查询时,只能使用一条order by子句(不允许使用多条order by子句)
包含或取消重复的行
union 操作符在查询时有一个默认行为,即从查询结果集中自动去除了重复的行。
比如之前我们记录的例子:
select
vend_id, prod_id, prod_price
from
products
where
prod_price <= 100
union
select
vend_id, prod_id, prod_price
from
products
where
vend_id in (1001, 1009);
在上述例子中:
- 第一条
select语句返回了 4 行数据,第二条select语句返回了 5 行数据,但是使用union操作符组合两条select语句后返回了 8 行数据(而不是 9 行)。 - 这是因为在第二条查询语句中,供应商 1009 生产的一种产品,价格也低于 100。而
union操作符从查询结果集中自动去除了重复的行(这种默认行为和使用多条where子句的效果一样)
如果我们想要改变这种 union 操作符的默认行为,使得所有的匹配行都可以返回,此时可以使用 union all。
比如:
select
vend_id, prod_id, prod_price
from
products
where
prod_price <= 100
union all
select
vend_id, prod_id, prod_price
from
products
where
vend_id in (1001, 1009);
记录:
union all是union的一种形式,它完成了where子句完成不了的工作- 如果确实需要每个条件的匹配行全部出现(包括重复行),则必须使用
union all而不是 多条where子句。
小结
在哪些情况下可以尝试使用组合查询呢?
如下所示:
- 在单个查询中从不同的表返回类似结构的数据
- 对单个表执行多个查询,按单个查询返回数据