在MySQL的实际开发场景中,经常需要将多个独立的查询语句返回的结果集整合为一个完整的结果集,比如需要统计不同分类下的数据总和、查询符合多个不同条件的数据记录等,这时候就需要用到合并查询结果的操作。合并查询结果可以让开发者不用在应用层做额外的结果拼接处理,直接通过SQL语句就能完成多组数据的整合。

MySQL合并查询结果的基本语法
MySQL中合并查询结果主要使用UNION和UNION ALL两个关键字,基本语法结构如下:
-- UNION语法 SELECT 列1, 列2, ... FROM 表1 WHERE 条件1 UNION SELECT 列1, 列2, ... FROM 表2 WHERE 条件2; -- UNION ALL语法 SELECT 列1, 列2, ... FROM 表1 WHERE 条件1 UNION ALL SELECT 列1, 列2, ... FROM 表2 WHERE 条件2;
两种语法的结构完全一致,都是把多个SELECT语句用对应的关键字连接起来,最终返回一个合并后的结果集。
UNION和UNION ALL的核心区别
两者最本质的差异在于是否对合并后的结果进行去重处理,具体差异如下:
| 对比维度 | UNION | UNION ALL |
|---|---|---|
| 去重逻辑 | 会自动对合并后的结果集进行去重,重复的记录只保留一条 | 不会进行去重处理,保留所有查询返回的记录,包括重复记录 |
| 性能表现 | 因为需要额外做去重排序操作,执行效率更低 | 不需要额外处理,执行效率更高 |
| 适用场景 | 需要最终结果无重复记录时使用 | 确认查询结果无重复,或者需要保留重复记录时使用 |
合并查询的使用注意事项
使用合并查询结果时,需要满足以下几个基本条件,否则语句会执行失败:
- 每个独立的
SELECT语句返回的列数必须完全一致,不能一个返回2列,另一个返回3列。 - 对应位置的列的数据类型必须兼容,比如第一个
SELECT的第一列是整型,第二个SELECT的第一列也必须是数值类型,不能是字符串类型。 - 列的名称以第一个
SELECT语句的列名为准,后续SELECT语句的列名不会生效,如果需要自定义列名,可以在第一个SELECT后面加别名。 - 如果需要对合并后的结果进行排序,只能在最后一个
SELECT语句后面加ORDER BY,并且排序字段要用第一个SELECT的列名或者列别名。
实际使用示例
示例1:使用UNION合并去重结果
假设有一张用户表user,里面存储了所有用户的信息,现在需要查询所有年龄小于20岁或者大于30岁的用户,并且结果不能重复:
-- 创建示例表
CREATE TABLE user (
id INT PRIMARY KEY,
name VARCHAR(50),
age INT
);
-- 插入示例数据
INSERT INTO user VALUES (1, '张三', 18);
INSERT INTO user VALUES (2, '李四', 25);
INSERT INTO user VALUES (3, '王五', 35);
INSERT INTO user VALUES (4, '赵六', 18);
-- 合并查询结果,去重
SELECT id, name, age FROM user WHERE age < 20
UNION
SELECT id, name, age FROM user WHERE age > 30;
上述语句执行后,会返回年龄18的张三和赵六,以及年龄35的王五,不会有重复记录。
示例2:使用UNION ALL合并保留重复结果
如果上述场景需要保留重复的年龄记录,比如两个查询条件有重叠,需要把所有符合的记录都列出来,就可以用UNION ALL:
-- 合并查询结果,保留重复 SELECT id, name, age FROM user WHERE age < 20 UNION ALL SELECT id, name, age FROM user WHERE age < 25;
上述语句执行后,年龄18的张三和赵六会各出现两次,因为同时满足两个查询条件,UNION ALL不会去重。
示例3:合并不同表的结果
假设还有一张会员表vip_user,存储了会员用户的信息,现在需要查询所有普通用户和会员用户的姓名和年龄,普通用户标记为用户类型,会员用户标记为会员类型:
-- 创建会员表示例
CREATE TABLE vip_user (
vip_id INT PRIMARY KEY,
vip_name VARCHAR(50),
vip_age INT
);
-- 插入会员示例数据
INSERT INTO vip_user VALUES (1, '孙七', 28);
INSERT INTO vip_user VALUES (2, '周八', 32);
-- 合并两个表的结果
SELECT name, age, '普通用户' AS user_type FROM user
UNION ALL
SELECT vip_name, vip_age, '会员用户' AS user_type FROM vip_user;
上述语句会把user表和vip_user表的数据合并,并且新增user_type列标记用户类型,因为两个表的列数、对应列的数据类型都一致,所以可以正常合并。
总结
合并查询结果是MySQL中非常实用的功能,UNION和UNION ALL的选择需要根据实际需求决定,如果明确结果无重复或者需要保留重复记录,优先使用UNION ALL可以提升查询性能。使用时一定要注意多个SELECT语句的列数、数据类型匹配,以及排序语法的正确位置,避免因语法问题导致查询失败。