如何运用Union-All在MySQL中巧妙合并多个查询结果集?
- 内容介绍
- 文章标签
- 相关推荐
本文共计594个文字,预计阅读时间需要3分钟。
直接使用 `UNION ALL` 语法,它不执行去重、排序、外部扫描,即将多个查询结果原样拼接起来,速度快、逻辑清晰,适合大量整数合场景。
列数和字段顺序必须严格一致
每个 SELECT 的列数量要一样,位置也要对齐。比如第一个查的是 id, name, status,后面所有查询都得按这个顺序来,不能第二个写成 name, id, status,否则数据会错位。
- 如果某张表缺某个字段,就用
NULL或默认值占位,例如:SELECT id, name, NULL AS city FROM t1 - 字段名以第一个 SELECT 为准,后续查询的列名会被忽略,想统一命名就在第一个里加别名
数据类型要兼容,别硬凑
对应位置的字段类型最好相同。MySQL 会尝试隐式转换,但有风险:
-
INT和DECIMAL可以转,一般没问题 -
VARCHAR(10)和VARCHAR(100)也能合并 - 但
TINYINT和DATETIME强行 UNION ALL 很可能报错或返回异常值
排序和分页只能放在最后
UNION ALL 是集合操作,不是嵌套结构,所以中间每个 SELECT 不能单独加 ORDER BY 或 LIMIT(除非用括号包成子查询)。
- 要整体排序:写在最后,如
... UNION ALL ... ORDER BY 1 DESC(按第一列降序) - 要限制总条数:
... UNION ALL ... LIMIT 20 - 如果某一边要取最新 5 条,得先在那一边子查询处理好,再参与 UNION ALL
什么时候该用 UNION ALL 而不是 UNION
只要你不依赖“自动去重”,基本都该选 UNION ALL:
- 查不同日期的订单(天然无重复)
- 合并线上和线下用户表(主键不重叠)
- 统计各渠道注册量,还要保留原始明细
- 大表合并时,UNION 多一次去重扫描,容易触发临时表和内存溢出
本文共计594个文字,预计阅读时间需要3分钟。
直接使用 `UNION ALL` 语法,它不执行去重、排序、外部扫描,即将多个查询结果原样拼接起来,速度快、逻辑清晰,适合大量整数合场景。
列数和字段顺序必须严格一致
每个 SELECT 的列数量要一样,位置也要对齐。比如第一个查的是 id, name, status,后面所有查询都得按这个顺序来,不能第二个写成 name, id, status,否则数据会错位。
- 如果某张表缺某个字段,就用
NULL或默认值占位,例如:SELECT id, name, NULL AS city FROM t1 - 字段名以第一个 SELECT 为准,后续查询的列名会被忽略,想统一命名就在第一个里加别名
数据类型要兼容,别硬凑
对应位置的字段类型最好相同。MySQL 会尝试隐式转换,但有风险:
-
INT和DECIMAL可以转,一般没问题 -
VARCHAR(10)和VARCHAR(100)也能合并 - 但
TINYINT和DATETIME强行 UNION ALL 很可能报错或返回异常值
排序和分页只能放在最后
UNION ALL 是集合操作,不是嵌套结构,所以中间每个 SELECT 不能单独加 ORDER BY 或 LIMIT(除非用括号包成子查询)。
- 要整体排序:写在最后,如
... UNION ALL ... ORDER BY 1 DESC(按第一列降序) - 要限制总条数:
... UNION ALL ... LIMIT 20 - 如果某一边要取最新 5 条,得先在那一边子查询处理好,再参与 UNION ALL
什么时候该用 UNION ALL 而不是 UNION
只要你不依赖“自动去重”,基本都该选 UNION ALL:
- 查不同日期的订单(天然无重复)
- 合并线上和线下用户表(主键不重叠)
- 统计各渠道注册量,还要保留原始明细
- 大表合并时,UNION 多一次去重扫描,容易触发临时表和内存溢出

