在SQL查询场景中,当我们需要把两个或多个独立查询的结果合并成一个完整的结果集时,UNION和UNION ALL是最常用的两个关键字。两者都能实现结果集的并集操作,但在去重逻辑、执行效率、适用场景上存在明显差异,下面我们逐一分析。
UNION和UNION ALL的基础用法
两个关键字的基础语法结构一致,都需要放在两个或多个SELECT语句之间,要求每个SELECT语句查询的字段数量、字段顺序、字段数据类型必须匹配,否则会直接报错。
基础语法如下:
-- UNION语法 SELECT column1, column2 FROM table1 UNION SELECT column1, column2 FROM table2; -- UNION ALL语法 SELECT column1, column2 FROM table1 UNION ALL SELECT column1, column2 FROM table2;
核心区别对比
1. 去重逻辑差异
UNION会对合并后的结果集进行去重操作,自动剔除所有重复的行;而UNION ALL不会做任何去重处理,直接将所有查询的结果按顺序拼接返回。
我们可以通过一个示例验证这个差异,假设存在如下用户表user_info:
| id | username | age |
|---|---|---|
| 1 | 张三 | 20 |
| 2 | 李四 | 22 |
| 3 | 张三 | 20 |
分别执行两个合并语句:
-- 使用UNION查询 SELECT username, age FROM user_info WHERE id IN (1,2) UNION SELECT username, age FROM user_info WHERE id IN (2,3); -- 使用UNION ALL查询 SELECT username, age FROM user_info WHERE id IN (1,2) UNION ALL SELECT username, age FROM user_info WHERE id IN (2,3);
UNION的查询结果会返回两行:张三 20、李四 22;而UNION ALL的查询结果会返回三行:张三 20、李四 22、张三 20,其中张三 20出现了两次。
2. 执行效率差异
因为UNION需要做去重操作,数据库在执行时会先合并所有结果,再对结果集进行排序、比对去重,这个过程会消耗额外的CPU和内存资源。而UNION ALL只需要直接拼接结果,不需要额外的计算步骤,因此执行效率远高于UNION。
如果合并的两个结果集本身没有重复数据,或者业务上允许重复数据存在,优先使用UNION ALL可以显著提升查询性能,尤其是在处理大数据量结果集时,性能差距会非常明显。
3. 适用场景差异
- 当业务要求合并后的结果集不能存在重复行,且无法提前确定原查询结果是否有重复时,使用UNION。
- 当明确知道多个查询结果之间没有重复数据,或者业务允许重复数据存在时,使用UNION ALL。
- 当合并的结果集数据量较大,对查询性能要求较高时,优先评估是否可以使用UNION ALL。
常见使用注意事项
字段匹配要求
使用UNION或UNION ALL时,每个SELECT语句的字段数量必须完全一致,字段顺序也需要对应,数据类型要兼容,否则会抛出语法错误。例如第一个SELECT查询了2个字段,第二个SELECT也必须查询2个字段,不能多也不能少。
排序规则
如果需要对合并后的结果集排序,ORDER BY子句只能放在最后一个SELECT语句之后,不能在每个SELECT语句中单独加ORDER BY,除非每个SELECT语句用括号包裹且搭配LIMIT子句。
正确的排序写法如下:
SELECT username, age FROM user_info WHERE id IN (1,2) UNION ALL SELECT username, age FROM user_info WHERE id IN (2,3) ORDER BY age DESC;
数据类型兼容
对应位置的字段数据类型需要兼容,比如第一个SELECT的第一个字段是INT类型,第二个SELECT的第一个字段也必须是数值类型,不能是字符串类型,否则会出现类型转换错误或者结果不符合预期。
总结
UNION和UNION ALL都是实现SQL结果集并集的有效方式,核心差异在于是否去重和执行效率。在实际开发中,我们需要根据业务需求、数据特征、性能要求选择合适的合并方式,避免无必要地使用UNION导致性能损耗,也不要在需要去重的场景下错误使用UNION ALL导致数据不准确。