本文详解MySQL UNION操作符的语法与用法,重点区分UNION(去重)与UNION ALL(保留重复)的性能差异。通过Websites与apps表的合并查询实例,展示如何合并多表数据、处理列数类型匹配及添加WHERE过滤条件,帮助开发者高效实现数据整合。
UNION操作符的核心作用与结果预览
MySQL UNION 操作符用于将两个或多个 SELECT 语句的结果集合并为一个单一的结果集。其核心特性在于自动去除结果集中的重复行,确保数据的唯一性。这对于需要从不同数据源提取相似结构数据进行汇总的场景非常有用。
操作前准备:理解数据源与约束
在使用 UNION 之前,必须确保参与合并的每个 SELECT 语句满足以下约束:
- 列数相同:每个
SELECT语句必须包含相同数量的列。 - 数据类型兼容:对应位置的列数据类型必须相同或兼容(例如,字符串与字符串,整数与整数)。
- 排序限制:
ORDER BY子句只能放在最后一个SELECT语句之后,用于对整个合并后的结果集进行排序。
基础语法结构
UNION 的基本语法格式如下:
SELECT column1, column2, ... FROM table1 WHERE condition1
UNION
SELECT column1, column2, ... FROM table2 WHERE condition2
ORDER BY column1, column2, ...;
参数说明:
column1, column2:要选择的列名,若选择所有列可使用*。table1, table2:数据来源表名。condition1, condition2:可选的过滤条件。ORDER BY:可选,用于指定最终结果集的排序方式。
实战演示:合并不同表的数据
为了直观展示 UNION 的效果,我们使用 MySQL 官方提供的 runoob 示例数据库中的两张表:Websites(网站信息)和 apps(应用信息)。
第1步:查看原始数据表结构
首先,我们需要了解两张表的数据内容,以便后续进行合并操作。
Websites 表数据:
mysql> SELECT * FROM Websites;
+----+--------------+---------------------------+-------+---------+
| id | name | url | alexa | country |
+----+--------------+---------------------------+-------+---------+
| 1 | Google | https://www.google.cm/ | 1 | USA |
| 2 | 淘宝 | https://www.taobao.com/ | 13 | CN |
| 3 | 菜鸟教程 | https://www.runoob.com/ | 4689 | CN |
| 4 | 微博 | https://weibo.com/ | 20 | CN |
| 5 | Facebook | https://www.facebook.com/ | 3 | USA |
| 7 | stackoverflow | https://stackoverflow.com/ | 0 | IND |
+----+---------------+---------------------------+-------+---------+
apps 表数据:
mysql> SELECT * FROM apps;
+----+------------+-------------------------+---------+
| id | app_name | url | country |
+----+------------+-------------------------+---------+
| 1 | QQ APP | https://im.qq.com/ | CN |
| 2 | 微博 APP | https://weibo.com/ | CN |
| 3 | 淘宝 APP | https://www.taobao.com/ | CN |
+----+------------+-------------------------+---------+
3 rows in set (0.00 sec)
第2步:使用 UNION 合并国家列(去重)
我们的目标是获取 Websites 和 apps 表中所有不重复的国家(country)列表。
SQL 语句如下:
SELECT country FROM Websites
UNION
SELECT country FROM apps
ORDER BY country;
执行结果:
+---------+
| country |
+---------+
| CN |
| IND |
| USA |
+---------+
3 rows in set (0.00 sec)
结果分析:虽然 Websites 表中有3条 CN 记录,apps 表中有3条 CN 记录,但 UNION 自动去重,最终结果中 CN 只出现了一次。这验证了 UNION 的核心功能:返回唯一值。
第3步:使用 UNION ALL 合并国家列(保留重复)
如果我们需要查看所有记录,包括重复的国家,应使用 UNION ALL。
SQL 语句如下:
SELECT country FROM Websites
UNION ALL
SELECT country FROM apps
ORDER BY country;
执行结果:
+---------+
| country |
+---------+
| CN |
| CN |
| CN |
| CN |
| CN |
| IND |
| USA |
| USA |
+---------+
8 rows in set (0.00 sec)
结果分析:结果集中包含了所有原始数据,CN 出现了5次(3+2),USA 出现了2次。这展示了 UNION ALL 的行为:不进行去重,直接合并。
第4步:结合 WHERE 子句进行过滤合并
在实际业务中,我们可能只需要合并特定条件下的数据。例如,只合并来自中国(CN)的网站和应用名称。
SQL 语句如下:
SELECT country, name FROM Websites
WHERE country='CN'
UNION ALL
SELECT country, app_name FROM apps
WHERE country='CN'
ORDER BY country;
执行结果:
+---------+--------------+
| country | name |
+---------+--------------+
| CN | 淘宝 |
| CN | 菜鸟教程 |
| CN | 微博 |
| CN | QQ APP |
| CN | 微博 APP |
| CN | 淘宝 APP |
+---------+--------------+
6 rows in set (0.00 sec)
关键点:虽然两张表的列名不同(name 和 app_name),但 UNION 只看列的位置和数据类型。第一列都是 country(字符串),第二列都是名称(字符串),因此可以成功合并。排序时按第一列 country 排序。
UNION 与 UNION ALL 的性能对比与选择建议
理解 UNION 和 UNION ALL 的区别不仅在于结果,更在于性能:
- UNION:执行时会进行额外的排序和去重操作(通常使用临时表和文件排序),因此性能开销较大。适用于确实需要唯一结果的场景。
- UNION ALL:直接合并结果集,不进行去重检查,执行速度更快。如果业务逻辑允许重复数据,或者后续步骤会处理重复,优先使用
UNION ALL以提升查询效率。
常见问题与注意事项
列数或数据类型不匹配怎么办?
如果两个 SELECT 语句的列数不同,或对应位置的数据类型不兼容(如整数与字符串),MySQL 会报错。解决方法是确保列数一致,并使用 CAST() 函数或 NULL 值进行类型转换。例如:
SELECT first_name, last_name FROM employees
UNION
SELECT department_name, NULL FROM departments;
这里使用 NULL 填充第二张表的第二列,以匹配第一张表的数据类型。
如何对 UNION 结果进行排序?
ORDER BY 子句必须放在整个 UNION 语句的最后。可以使用列名或列序号进行排序。例如:
SELECT country, name FROM Websites
UNION
SELECT country, app_name FROM apps
ORDER BY 1;
这里 ORDER BY 1 表示按第一列(country)排序。
总结
MySQL UNION 操作符是合并多个查询结果集的强大工具。掌握其语法要点——列数相同、类型兼容、去重特性——是正确使用的前提。在实际开发中,应根据业务需求选择 UNION(去重)或 UNION ALL(保留重复,性能更优)。通过结合 WHERE 子句和 ORDER BY,可以实现灵活且高效的数据整合。
以上就是MySQL UNION操作符的详细内容,更多关于MySQL数据库教程的资料请关注本站其它相关文章!
