SQL中的UNION和UNION ALL是用于合并多个SELECT语句查询结果集的操作符,二者在功能上有相似性,但在执行逻辑和适用场景上存在明显差异,合理选择二者可以大幅提升查询效率。

UNION 与 UNION ALL 的核心区别
二者最本质的差异在于是否对合并后的结果集进行去重处理,同时这也直接影响了执行效率。
1. 去重逻辑差异
UNION操作符在合并多个查询结果后,会自动对最终的结果集进行去重操作,删除重复的行记录;而UNION ALL仅做结果集的简单拼接,不会进行任何去重处理,会保留所有查询返回的行,包括重复记录。
2. 执行效率差异
由于UNION需要额外执行去重操作,通常会涉及排序或者哈希去重的步骤,因此执行开销比UNION ALL更高。在数据量较大或者查询结果本身不存在重复的场景下,使用UNION ALL可以明显减少查询耗时。
3. 使用限制
无论是UNION还是UNION ALL,合并的多个SELECT语句都需要满足两个基本条件:一是每个SELECT语句返回的列数必须相同;二是对应位置的列的数据类型必须兼容,否则查询会直接报错。
使用示例
假设我们有两个用户表,分别是user_active(活跃用户表)和user_inactive(非活跃用户表),表结构一致,都包含id、username、age三个字段。
使用 UNION 合并结果
如果需要获取所有用户的不重复记录,可以使用以下语句:
-- 合并两个表的所有用户记录,自动去重 SELECT id, username, age FROM user_active UNION SELECT id, username, age FROM user_inactive;
使用 UNION ALL 合并结果
如果确认两个表的用户没有重叠,或者需要保留所有记录(包括可能的重复),可以使用以下语句:
-- 合并两个表的所有用户记录,不去重 SELECT id, username, age FROM user_active UNION ALL SELECT id, username, age FROM user_inactive;
高效使用建议
- 如果明确知道多个查询的结果集不存在重复记录,或者业务上允许存在重复记录,优先选择
UNION ALL,减少不必要的去重开销。 - 如果业务要求结果集必须去重,再使用
UNION,避免无意义的去重操作浪费性能。 - 合并查询前可以先检查每个SELECT语句的返回列数和数据类型,避免因不匹配导致查询失败。
- 如果需要对合并后的结果进行排序,建议只在最后一个SELECT语句后添加ORDER BY子句,排序会作用于整个合并后的结果集。
常见问题说明
很多开发者会疑惑UNION的去重规则是什么,实际上UNION的去重是针对整行记录而言的,只有当两个行的所有列值都完全相同时,才会被判定为重复记录并删除多余的行。
另外需要注意,UNION和UNION ALL都不会改变每个SELECT语句原本的排序逻辑,如果需要整体排序,必须单独添加ORDER BY子句,不能直接在每个SELECT内部加ORDER BY而不加整体排序,这种写法在部分数据库中是不被支持的。