首页MySQL联合查询 UNION Clause
Created At : 2021-11-13
Last Updated: 2022-02-10

联合查询 UNION Clause

利用UNION关键字,可以给出多条SELECT语句,并将它们的结果组合成单个结果集。

合并时,两个表对应的列数和数据类型必须相同。

UNION 合并之意,组合查询,也称复合查询(compound query

有两种基本情况,其中需要使用组合查询:

❑ 在单个查询中从不同的表返回类似结构的数据;

❑ 对单个表执行多个查询,按单个查询返回数据;

TIP

组合查询和多个WHERE条件

多数情况下,组合相同表的两个查询完成的工作与具有多个WHERE子句条件的单条查询完成的工作相同。

换句话说,任何具有多个WHERE子句的SELECT语句都可以作为一个组合查询给出

创建组合查询

可用UNION操作符来组合数条SQL查询。

利用UNION,可给出多条SELECT语句,将它们的结果组合成单个结果集。

UNION的具体使用

例如,假如需要价格小于等于5的所有物品的一个列表,而且还想包括供应商1001和1002生产的所有物品(不考虑价格)。

操作分解演示

-- 1) 步骤1:查询价格小于5的物品列表
SELECT vend_id, prod_id, prod_price
  FROM products
  WHERE prod_price <= 5;
-- +---------+---------+------------+
-- | vend_id | prod_id | prod_price |
-- +---------+---------+------------+
-- |    1003 | FC      |       2.50 |
-- |    1002 | FU1     |       3.42 |
-- |    1003 | SLING   |       4.49 |
-- |    1003 | TNT1    |       2.50 |
-- +---------+---------+------------+

-- 2) 步骤2:查询供应商1001和1002生产的所有物品
SELECT vend_id, prod_id, prod_price
  FROM products
  WHERE vend_id IN (1001, 1002);
-- +---------+---------+------------+
-- | vend_id | prod_id | prod_price |
-- +---------+---------+------------+
-- |    1001 | ANV01   |       5.99 |
-- |    1001 | ANV02   |       9.99 |
-- |    1001 | ANV03   |      14.99 |
-- |    1002 | FU1     |       3.42 |
-- |    1002 | OL1     |       8.99 |
-- +---------+---------+------------+

-- 3) 步骤3:使用UNION合并查询结果
SELECT vend_id, prod_id, prod_price
  FROM products
  WHERE prod_price <= 5
UNION
SELECT vend_id, prod_id, prod_price
  FROM products
  WHERE vend_id IN (1001, 1002);
-- +---------+---------+------------+
-- | vend_id | prod_id | prod_price |
-- +---------+---------+------------+
-- |    1003 | FC      |       2.50 |
-- |    1002 | FU1     |       3.42 |
-- |    1003 | SLING   |       4.49 |
-- |    1003 | TNT1    |       2.50 |
-- |    1001 | ANV01   |       5.99 |
-- |    1001 | ANV02   |       9.99 |
-- |    1001 | ANV03   |      14.99 |
-- |    1002 | OL1     |       8.99 |
-- +---------+---------+------------+

⚡ 默认情况下,UNION 删除的重复的行。

以上是以上UNION组合查询,如果使用where多条件查询,结果相同:

SELECT vend_id, prod_id, prod_price
  FROM products
  WHERE prod_price <= 5
     OR vend_id IN (1001, 1002);

UNION规则

在进行并时有几条规则需要注意。

❑ UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔(因此,如果组合4条SELECT语句,将要使用3个UNION关键字)。

❑ UNION中的每个查询必须包含相同的列、表达式或聚集函数(不过各个列不需要以相同的次序列出)。

❑ 列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含地转换的类型(例如,不同的数值类型或不同的日期类型)。

包含或取消重复的行

如上所述:

默认情况下,UNION从查询结果集中自动去除了重复的行。

如果想返回所有匹配行,可使用UNION ALL而不是UNION。

-- use UNION ALL 返回所有行,不删除重复行
SELECT vend_id, prod_id, prod_price
  FROM products
  WHERE prod_price <= 5
UNION ALL
SELECT vend_id, prod_id, prod_price
  FROM products
  WHERE vend_id IN (1001, 1002);
-- +---------+---------+------------+
-- | vend_id | prod_id | prod_price |
-- +---------+---------+------------+
-- |    1003 | FC      |       2.50 |
-- |    1002 | FU1     |       3.42 |
-- |    1003 | SLING   |       4.49 |
-- |    1003 | TNT1    |       2.50 |
-- |    1001 | ANV01   |       5.99 |
-- |    1001 | ANV02   |       9.99 |
-- |    1001 | ANV03   |      14.99 |
-- |    1002 | FU1     |       3.42 |
-- |    1002 | OL1     |       8.99 |
-- +---------+---------+------------+

对组合查询结果排序

在用UNION组合查询时,只能使用一条ORDER BY子句,它必须出现在最后一条SELECT语句之后

-- sort UNION result
SELECT vend_id, prod_id, prod_price
  FROM products
  WHERE prod_price <= 5
UNION
SELECT vend_id, prod_id, prod_price
  FROM products
  WHERE vend_id IN (1001, 1002)
ORDER BY vend_id, prod_id;
-- +---------+---------+------------+
-- | vend_id | prod_id | prod_price |
-- +---------+---------+------------+
-- |    1001 | ANV01   |       5.99 |
-- |    1001 | ANV02   |       9.99 |
-- |    1001 | ANV03   |      14.99 |
-- |    1002 | FU1     |       3.42 |
-- |    1002 | OL1     |       8.99 |
-- |    1003 | FC      |       2.50 |
-- |    1003 | SLING   |       4.49 |
-- |    1003 | TNT1    |       2.50 |
-- +---------+---------+------------+

这条UNION在最后一条SELECT语句后使用了ORDER BY子句。

虽然ORDER BY子句似乎只是最后一条SELECT语句的组成部分,但实际上MySQL将用它来排序所有SELECT语句返回的所有结果。