应优先使用 union all,因其不排序、不去重、不额外扫描,仅原样拼接结果,速度快且逻辑清晰;需确保各查询列数、顺序、类型兼容,字段名以首个 select 为准,排序和分页须置于最后。

直接用 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 多一次去重扫描,容易触发临时表和内存溢出











