第 18.1 节:使用 UNION 组合 SELECT 语句

你可以使用 UNION 关键字组合两个结构相同的查询的结果。

例如,如果你想要从两个独立的表(例如 authors 和 editors)中获取所有联系信息,可以像这样使用 UNION:

SELECT name, email, phone_number FROM authors
UNION
SELECT name, email, phone_number FROM editors;

单独使用 UNION 会去除重复行。如果你需要保留重复行,可以使用 ALL 关键字:UNION ALL。

第 18.2 节:组合不同列的数据

SELECT name, caption AS title, year, pages FROM books
UNION
SELECT name, title, year, 0 AS pages FROM movies;

当组合两个具有不同列的结果集时,使用默认值来模拟缺失的列。

第 18.3 节:ORDER BY

如果你需要对 UNION 的结果进行排序,请使用以下模式:

(SELECT ...) UNION (SELECT ...) ORDER BY ...

如果没有括号,最终的 ORDER BY 将属于最后一个 SELECT。

第 18.4 节:通过 OFFSET 进行分页

当向 UNION 添加 LIMIT 时,应使用以下模式:

(SELECT ... ORDER BY x LIMIT 10)
UNION
(SELECT ... ORDER BY x LIMIT 10)
ORDER BY x LIMIT 10;

由于你无法预测哪些行来自哪个 SELECT,你需要从每个 SELECT 中获取 10 行,然后进一步缩减列表,同时重复使用 ORDER BY 和 LIMIT。

对于第 4 页(每页 10 项),需要使用以下模式:

(SELECT ... ORDER BY x LIMIT 40)
UNION
(SELECT ... ORDER BY x LIMIT 40)
ORDER BY x LIMIT 30, 10;

也就是说,先从每个 SELECT 中收集 4 页的数据量,然后在 UNION 中执行 OFFSET。

第 18.5 节:合并和组合不同 MySQL 表上的数据(具有相同列)为唯一行并执行查询

以下 UNION ALL 组合了多个表中的数据,并作为一个表别名供你的查询使用:

SELECT
    YEAR(date_time_column),
    MONTH(date_time_column),
    MIN(DATE(date_time_column)),
    MAX(DATE(date_time_column)),
    COUNT(DISTINCT (ip)),
    COUNT(ip),
    (COUNT(ip) / COUNT(DISTINCT (ip))) AS Ratio
FROM (
    SELECT date_time_column, ip FROM server_log_1 WHERE state = 'action' AND log_id = 150
    UNION ALL
    SELECT date_time_column, ip FROM server_log_2 WHERE state = 'action' AND log_id = 150
    UNION ALL
    SELECT date_time_column, ip FROM server_log_3 WHERE state = 'action' AND log_id = 150
    UNION ALL
    SELECT date_time_column, ip FROM server_log WHERE state = 'action' AND log_id = 150
) AS table_all
GROUP BY YEAR(date_time_column), MONTH(date_time_column);

第 18.6 节:UNION ALL 与 UNION

SELECT 1,22,44 UNION SELECT 2,33,55;

结果:

1 22 44
1 22 44
2 33 55
SELECT 1,22,44 UNION SELECT 2,33,55 UNION SELECT 2,33,55;

结果与上面相同(因为 UNION 去重)。

使用 UNION ALL:

SELECT 1,22,44 UNION SELECT 2,33,55 UNION ALL SELECT 2,33,55;

结果:

1 22 44
1 22 44
2 33 55
2 33 55