第 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 |