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

6次阅读

UNION ALL 与 UNION 仅差 ALL 关键字,但前者跳过去重排序、后者隐式 DISTINCT 并默认排序;二者均要求列数一致、类型兼容、顺序对齐,且 ORDER BY/LIMIT 必须置于末尾作用于整体结果。

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

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

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

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

  • UNION 会隐式加 DISTINCT + 默认按第一列排序(除非显式禁用)
  • UNION ALL 完全跳过去重和排序步骤,只是把两个结果集物理拼接
  • 两者都要求:每个 SELECT 的列数必须一致,对应列类型需兼容(如 INTBIGINT 隐式转换,但 DATEVARCHAR 不行,得用 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 BYUNION / UNION ALL 中不是可选修饰,而是顶层指令,它对整个合并后结果生效。

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

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

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

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

星耀云
版权声明:本站原创文章,由 星耀云 2026-01-05发表,共计1451字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources