MySQL 查询中的 UNION、UNION ALL 和 DISTINCT
MySQL 查询中的 UNION、UNION ALL 和 DISTINCT
1. UNION 操作符
UNION 用于合并两个或多个 SELECT 语句的结果集,并自动去除重复行。
语法:
SELECT column1, column2 FROM table1
UNION
SELECT column1, column2 FROM table2;
特点:
- 合并结果时会自动去重
- 每个 SELECT 语句必须有相同数量的列
- 列的数据类型必须兼容
- 结果集的列名取自第一个 SELECT 语句
示例:合并北京和上海两个分公司的员工名单,确保不重复
-- 北京分公司员工表
CREATE TABLE employees_beijing (id INT PRIMARY KEY,name VARCHAR(50),position VARCHAR(50)
);-- 上海分公司员工表
CREATE TABLE employees_shanghai (id INT PRIMARY KEY,name VARCHAR(50),position VARCHAR(50)
);-- 插入数据
INSERT INTO employees_beijing VALUES
(1, '张三', '经理'),
(2, '李四', '开发工程师'),
(3, '王五', '产品经理');INSERT INTO employees_shanghai VALUES
(2, '李四', '开发工程师'), -- 与北京分公司重复
(4, '赵六', 'UI设计师'),
(5, '钱七', '测试工程师');-- 使用UNION合并并去重
SELECT id, name, position FROM employees_beijing
UNION
SELECT id, name, position FROM employees_shanghai
ORDER BY name;
结果:李四只出现一次,尽管在两个表中都存在
id | name | position |
---|---|---|
1 | 张三 | 经理 |
2 | 李四 | 开发工程师 |
3 | 王五 | 产品经理 |
4 | 赵六 | UI设计师 |
5 | 钱七 | 测试工程师 |
2. UNION ALL 操作符
UNION ALL 也用于合并结果集,但保留所有行,包括重复行。
语法:
SELECT column1, column2 FROM table1
UNION ALL
SELECT column1, column2 FROM table2;
特点:
- 不进行去重操作,性能比 UNION 高
- 其他规则与 UNION 相同
示例:统计两个部门的所有项目记录,包括重复项目
-- 开发部门项目表
CREATE TABLE dev_projects (project_id INT,project_name VARCHAR(50),start_date DATE
);-- 测试部门项目表
CREATE TABLE test_projects (project_id INT,project_name VARCHAR(50),start_date DATE
);-- 插入数据
INSERT INTO dev_projects VALUES
(101, '电商平台', '2023-01-01'),
(102, 'CRM系统', '2023-02-15'),
(103, '数据中台', '2023-03-10');INSERT INTO test_projects VALUES
(102, 'CRM系统', '2023-02-15'), -- 与开发部门重复
(104, '移动APP', '2023-04-05'),
(105, '小程序', '2023-05-20');-- 使用UNION ALL合并(保留重复)
SELECT project_id, project_name, '开发部' AS department
FROM dev_projects
UNION ALL
SELECT project_id, project_name, '测试部' AS department
FROM test_projects
ORDER BY project_id;
结果:重复记录(102,CRM系统)保留
project_id | project_name | department |
---|---|---|
101 | 电商平台 | 开发部 |
102 | CRM系统 | 开发部 |
102 | CRM系统 | 测试部 |
103 | 数据中台 | 开发部 |
104 | 移动APP | 测试部 |
105 | 小程序 | 测试部 |
3. DISTINCT 关键字
DISTINCT 用于返回唯一不同的值,去除结果集中的重复行。
语法:
SELECT DISTINCT column1, column2 FROM table_name;
特点:
- 作用于整个 SELECT 列表
- 可以用于聚合函数内
- 会影响查询性能,特别是大数据量时
示例:从销售记录中找出所有不同的产品类别和客户城市
-- 销售记录表
CREATE TABLE sales (id INT PRIMARY KEY,product_name VARCHAR(50),category VARCHAR(30),customer_city VARCHAR(30),sale_date DATE,amount DECIMAL(10,2)
);-- 插入数据
INSERT INTO sales VALUES
(1, 'iPhone 13', '手机', '北京', '2023-01-10', 5999.00),
(2, '华为Mate50', '手机', '上海', '2023-01-15', 4999.00),
(3, 'iPad Pro', '平板', '广州', '2023-02-05', 4799.00),
(4, 'MacBook Air', '笔记本', '北京', '2023-02-10', 7999.00),
(5, '华为Mate50', '手机', '北京', '2023-03-12', 4999.00),
(6, '小米电视', '家电', '上海', '2023-03-15', 3299.00),
(7, 'iPhone 13', '手机', '广州', '2023-04-20', 5999.00);-- 查询所有不同的产品类别
SELECT DISTINCT category FROM sales;
结果:
category |
---|
手机 |
平板 |
笔记本 |
家电 |
-- 查询每个城市的不同产品类别
SELECT DISTINCT customer_city, category
FROM sales
ORDER BY customer_city, category;
结果:
customer_city | category |
---|---|
北京 | 笔记本 |
北京 | 手机 |
上海 | 家电 |
上海 | 手机 |
广州 | 平板 |
广州 | 手机 |
-- 结合COUNT计算不同城市的数量
SELECT COUNT(DISTINCT customer_city)
AS city_count
FROM sales;
结果:
city_count |
---|
3 |
三者的比较
特性 | UNION | UNION ALL | DISTINCT |
---|---|---|---|
去重 | 是 | 否 | 是 |
合并结果集 | 是 | 是 | 否 |
性能 | 较低 | 较高 | 取决于数据 |
使用场景 | 需要合并并去重 | 需要合并但保留重复 | 单表去重 |
实际应用建议
- 优先使用 UNION ALL:当确定结果没有重复或需要保留重复时,使用 UNION ALL 性能更好
- DISTINCT 慎用:大数据量时 DISTINCT 可能成为性能瓶颈,考虑用 GROUP BY 替代
- 列匹配:使用 UNION/UNION ALL 时确保各 SELECT 语句的列数和类型匹配
- ORDER BY 位置:在 UNION 查询中,ORDER BY 应放在最后一个 SELECT 语句后