Skip to main content

MySQL联合:组合两个或多个查询的结果

MySQL联合运算符

MySQL UNION运算符允许您将两个或多个查询结果集组合成一个结果集。下面说明了UNION运算符的语法:

SELECT column_list
UNION [DISTINCT | ALL]
SELECT column_list
UNION [DISTINCT | ALL]
SELECT column_list
...

要使用UNION运算符组合两个或多个查询的结果集,必须遵循以下基本规则:

默认情况下,即使未明确指定DISTINCT运算符,UNION运算符也会删除重复的行。

让我们看看下面的示例表:t1和t2:

DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;

CREATE TABLE t1 (
id INT PRIMARY KEY
);

CREATE TABLE t2 (
id INT PRIMARY KEY
);

INSERT INTO t1 VALUES (1),(2),(3);
INSERT INTO t2 VALUES (2),(3),(4);

下面的语句组合了从t1和t2表返回的结果集:

SELECT id
FROM t1
UNION
SELECT id
FROM t2;

最终结果集包含来自查询返回的单独结果集的不同值:

+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
+----+
4 rows in set (0.00 sec)

因为值为2和3的行是重复的,所以联合会将它们删除,只保留唯一的值。

下面的维恩图说明了来自t1和t2表的两个结果集的并集:

如果显式使用UNION ALL,重复行(如果可用)将保留在结果中。因为UNION ALL不需要处理重复项,所以它的执行速度比UNION DISTINCT快。

SELECT id
FROM t1
UNION ALL
SELECT id
FROM t2;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 2 |
| 3 |
| 4 |
+----+
6 rows in set (0.00 sec)

如您所见,由于UNION ALL操作,重复项出现在组合结果集中。

联盟vs.加入

联接水平合并结果集,并集垂直追加结果集。下图说明了UNION和JOIN之间的区别:

MySQL UNION vs JOIN

MySQL联合和列别名示例

我们将使用示例数据库中的customers和employees表进行演示:

假设要将员工和客户的名字和姓氏组合到一个结果集中,可以使用UNION运算符,如下所示:

SELECT 
firstName,
lastName
FROM
employees
UNION
SELECT
contactFirstName,
contactLastName
FROM
customers;

MySQL UNION example

从输出中可以看到,MySQL联合使用第一条SELECT语句的列名作为输出的列标题。

如果要使用其他列标题,需要在第一个SELECT语句中显式使用列别名,如下例所示:

SELECT 
CONCAT(firstName,' ',lastName) fullname
FROM
employees
UNION SELECT
CONCAT(contactFirstName,' ',contactLastName)
FROM
customers;

<img class=“alignnone size full wp-image-6375”src=”https://www.mysqltutorial.org/wp-content/uploads/2009/12/MySQL-UNION-with-column-alias-example.png“alt=“MySQL UNION with column alias example”width=“118”height=“215”>

本例使用第一个查询的列标题作为输出。它使用CONCAT()函数将名字、空格和姓氏连接成全名。

MySQL联盟和订单管理

如果要对联合的结果集进行排序,请在最后一条SELECT语句中使用ORDER BY子句,如下例所示:

SELECT 
concat(firstName,' ',lastName) fullname
FROM
employees
UNION SELECT
concat(contactFirstName,' ',contactLastName)
FROM
customers
ORDER BY fullname;

MySQL UNION and ORDER BY example

请注意,如果在每个SELECT语句中放置ORDER BY子句,则不会影响最终结果集中行的顺序。

要区分员工和客户,可以添加一列,如下查询所示:

SELECT 
CONCAT(firstName, ' ', lastName) fullname,
'Employee' as contactType
FROM
employees
UNION SELECT
CONCAT(contactFirstName, ' ', contactLastName),
'Customer' as contactType
FROM
customers
ORDER BY
fullname

MysQL Union with a custom column

MySQL还提供了另一个选项,可以使用ORDER BY子句根据列位置对结果集进行排序,如下所示:

SELECT 
CONCAT(firstName,' ',lastName) fullname
FROM
employees
UNION SELECT
CONCAT(contactFirstName,' ',contactLastName)
FROM
customers
ORDER BY 1;

然而,按列位置对结果集进行排序并不是一种好的做法。

在本教程中,您学习了如何使用MySQL UNION语句将来自多个查询的数据组合到单个结果集中。