MySQL UNION

摘要在本教程中,您将学习如何使用 MySQL UNION运算符将多个SELECT语句中的两个或多个结果集合并为一个结果集。

MySQL UNION运算符

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

SELECT column_list
UNION [DISTINCT | ALL]
SELECT column_list
UNION [DISTINCT | ALL]
SELECT column_list
...Code language: SQL (Structured Query Language) (sql)

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

  • 首先,所有SELECT语句中出现的列的数量和顺序必须相同。
  • 其次,列的数据类型必须相同或兼容。

默认情况下,即使您没有显式指定DISTINCT运算符, UNION运算符也会删除重复行

让我们看看以下示例表: t1t2

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);Code language: SQL (Structured Query Language) (sql)

以下语句组合了从t1t2表返回的结果集:

SELECT id
FROM t1
UNION
SELECT id
FROM t2;Code language: SQL (Structured Query Language) (sql)

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

+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
+----+
4 rows in set (0.00 sec)Code language: SQL (Structured Query Language) (sql)

由于值 2 和 3 的行是重复的,因此UNION删除了它们并仅保留唯一值。

以下维恩图说明了来自t1t2表的两个结果集的并集:

MySQL UNION

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

SELECT id
FROM t1
UNION ALL
SELECT id
FROM t2;Code language: SQL (Structured Query Language) (sql)
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  2 |
|  3 |
|  4 |
+----+
6 rows in set (0.00 sec)Code language: SQL (Structured Query Language) (sql)

正如您所看到的,由于UNION ALL操作,重复项出现在合并结果集中。

UNIONJOIN

JOIN水平组合结果集, UNION垂直附加结果集。下图说明了UNIONJOIN的区别:

MySQL UNION 与 JOIN

MySQL UNION和列别名示例

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

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

SELECT 
    firstName, 
    lastName
FROM
    employees 
UNION 
SELECT 
    contactFirstName, 
    contactLastName
FROM
    customers;Code language: SQL (Structured Query Language) (sql)
MySQL UNION example

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

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

SELECT 
    CONCAT(firstName,' ',lastName) fullname
FROM
    employees 
UNION SELECT 
    CONCAT(contactFirstName,' ',contactLastName)
FROM
    customers;Code language: SQL (Structured Query Language) (sql)

MySQL UNION 与列别名示例

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

MySQL UNIONORDER BY

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

SELECT 
    concat(firstName,' ',lastName) fullname
FROM
    employees 
UNION SELECT 
    concat(contactFirstName,' ',contactLastName)
FROM
    customers
ORDER BY fullname;Code language: SQL (Structured Query Language) (sql)
MySQL UNION and ORDER BY example

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

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

SELECT 
    CONCAT(firstName, ' ', lastName) fullname, 
    'Employee' as contactType
FROM
    employees 
UNION SELECT 
    CONCAT(contactFirstName, ' ', contactLastName),
    'Customer' as contactType
FROM
    customers
ORDER BY 
    fullnameCode language: SQL (Structured Query Language) (sql)
具有自定义列的 MySQL Union

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

SELECT 
    CONCAT(firstName,' ',lastName) fullname
FROM
    employees 
UNION SELECT 
    CONCAT(contactFirstName,' ',contactLastName)
FROM
    customers
ORDER BY 1;Code language: SQL (Structured Query Language) (sql)

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

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

本教程有帮助吗?