union all在语法上有什么不同_mysql合并规则说明

来源:这里教程网 时间:2026-02-28 20:37:40 作者:

UNION ALL 和 UNION 的语法差异只在关键字本身

语法上,

UNION ALL
UNION
唯一区别就是多了一个
ALL
关键字——它不改变 SELECT 结构、不新增括号、不调整列顺序,也不影响 WHERE 或 JOIN 的写法。

但这个“小改动”直接决定了 MySQL 怎么处理重复行和执行计划:

UNION
会隐式加
DISTINCT
+ 默认按第一列排序(除非显式禁用)
UNION ALL
完全跳过去重和排序步骤,只是把两个结果集物理拼接
两者都要求:每个
SELECT
的列数必须一致,对应列类型需兼容(如
INT
BIGINT
可隐式转换,但
DATE
VARCHAR
不行,得用
CAST

列名、类型、顺序这三项必须对齐,否则直接报错

MySQL 合并时不会帮你“猜意图”,而是严格校验结构。常见报错

Error 1222: The used SELECT statements have a different number of columns
就是列数不一致。

实操建议:

列名取自第一个
SELECT
的别名(比如
SELECT name AS title FROM a UNION SELECT username FROM b
,结果列名是
title
类型不匹配时,宁可显式
CAST
也不要依赖隐式转换(例如
SELECT CAST(created_at AS CHAR) FROM orders UNION ALL SELECT update_time FROM logs
如果表字段顺序不同(如
users(id, name)
vs
admins(name, id)
),必须手动调整 SELECT 列序:
SELECT id, name FROM users UNION ALL SELECT id, name FROM admins

ORDER BY 和 LIMIT 必须放在最后,且只能作用于整个结果集

你不能在每个子查询里单独写

ORDER BY
来控制合并顺序——MySQL 会忽略它(除非配合
LIMIT
,但仍有风险)。

正确写法只有一种结构:

SELECT id, name FROM table1
UNION ALL
SELECT id, name FROM table2
ORDER BY id DESC
LIMIT 20;

错误写法(会报语法错误或行为不可控):

(SELECT id, name FROM table1 ORDER BY id) 
UNION ALL 
(SELECT id, name FROM table2 ORDER BY id);

注意:

ORDER BY
UNION
/
UNION ALL
中不是可选修饰,而是顶层指令,它对整个合并后结果生效。

什么时候必须用 UNION,什么时候该死守 UNION ALL

别凭感觉选。关键看数据语义和性能预期:

UNION
:跨业务系统拉取「用户列表」,怕同一人出现在多个源表中;报表去重统计唯一设备 ID
UNION ALL
:日志表(
log_202512
+
log_202601
)合并查错误;过程表和归档表联合分页(确认无主键重叠)
性能陷阱:即使你加了
WHERE
过滤,
UNION
仍要对最终结果做全局去重,大结果集下 I/O 和临时表开销陡增
安全提示:如果用了
UNION
却没检查是否真有重复数据,可能掩盖数据质量问题(比如双写导致同一条订单进了两张表)

最常被忽略的一点:UNION 的“去重”是全字段比对,不是按主键。哪怕两行只有时间戳差 1 秒,也会算作不同行——所以别指望它替你 dedupe 业务逻辑意义上的重复。

相关推荐