MySQL中的UNION操作符

前言

在MySQL数据库的世界里,数据查询是一项核心操作。而UNION操作符作为数据查询中的一个强大工具,能够帮助开发者高效地处理多个结果集的合并。

1. 什么是UNION操作符

在MySQL中,UNION并不是一个函数,而是一个用于合并两个或多个SELECT语句结果集的操作符。它就像是一个数据整合器,将不同SELECT语句获取到的数据合并在一起,形成一个统一的结果集,方便用户进行数据分析和处理。

2. 基本语法

UNION操作符的基本语法结构如下:

sql 复制代码
SELECT column1, column2,...
FROM table1
UNION
SELECT column3, column4,...
FROM table2;

在这个语法中,首先是第一个SELECT查询,它从table1表中选择指定的列column1, column2,... 。然后通过UNION操作符,将其与第二个SELECT查询的结果进行合并,第二个查询从table2表中选择列column3, column4,...

3. 字段要求

3.1 列数必须相同

使用UNION时,一个严格的要求是所有参与UNION操作的SELECT语句中的列数必须相同。这是因为UNION操作本质上是按行将多个结果集纵向拼接,只有列数一致,才能确保每一行的数据在合并后有正确的列对应关系。例如:

sql 复制代码
-- 正确示例,列数相同
SELECT id, name
FROM users
UNION
SELECT product_id, product_name
FROM products;

-- 错误示例,列数不同
SELECT id, name
FROM users
UNION
SELECT product_id, product_name, price
FROM products;

上述错误示例中,第一个SELECT语句选择了2列,而第二个SELECT语句选择了3列 ,MySQL会抛出语法错误。

3.2 对应列数据类型兼容

除了列数相同,对应列的数据类型也必须兼容。所谓兼容,指的是数据类型要么完全相同,要么可以在MySQL中进行隐式类型转换。例如,如果第一个SELECT语句中的某列是INT类型,那么第二个SELECT语句中对应位置的列也应该是INT类型,或者是可以隐式转换为INT类型的数据类型,如SMALLINTTINYINT 等数值类型。

sql 复制代码
-- 正确示例,数据类型兼容
SELECT id, name
FROM users
UNION
SELECT CAST(order_id AS SIGNED), customer_name
FROM orders;

-- 错误示例,数据类型不兼容
SELECT id, name
FROM users
UNION
SELECT order_date, customer_name
FROM orders;

上述错误示例中,id是数值类型,而order_date是日期类型,两者不兼容,无法进行UNION操作。

3.3 列名以首个SELECT为准

值得注意的是,在UNION操作中,结果集的列名通常会以第一个SELECT语句中的列名为准。即使后续SELECT语句中列的别名不同,最终结果集也会采用第一个SELECT的列名。例如:

sql 复制代码
SELECT id AS user_id, name AS user_name
FROM users
UNION
SELECT product_id, product_name
FROM products;

在这个例子中,最终结果集的列名是user_iduser_name ,而不是product_idproduct_name

4. 特点

4.1 结果集去重

默认情况下,UNION操作会去除合并结果集中的重复行。这意味着,如果两个SELECT语句返回的结果中有相同的行,最终只会在结果集中出现一次。例如:

sql 复制代码
SELECT 'apple' AS fruit
UNION
SELECT 'apple' AS fruit;

上述查询结果只会包含一行'apple' ,重复的行被去除了。

4.2 结果集排序

UNION操作后的结果集可以使用ORDER BY子句进行排序。如果没有指定ORDER BY,则结果集的顺序是不确定的。需要注意的是,ORDER BY子句通常放在最后一个SELECT语句之后,它会对整个UNION操作后的结果集进行排序。例如:

sql 复制代码
SELECT name, salary
FROM employees
UNION
SELECT name, salary
FROM contractors
ORDER BY salary DESC;

上述查询会先合并employees表和contractors表中的数据,然后按照salary列降序排列整个结果集。

4.3 性能考虑

UNION操作在合并结果集时可能会有一定的性能开销,特别是在处理大量数据时。这是因为UNION默认会去除重复的行,这个去重过程需要额外的计算资源。如果使用UNION ALL,由于不需要去除重复行,性能可能会更好一些。因此,在实际应用中,如果能够确定合并后的结果集中不会有重复行,或者重复行对业务没有影响,那么优先选择UNION ALL可以提高查询效率。

5. 示例

假设有两个表employeescontractors,它们都包含namesalary列,以下是使用UNIONUNION ALL的示例:

5.1 使用UNION

sql 复制代码
SELECT name, salary
FROM employees
UNION
SELECT name, salary
FROM contractors;

上述查询会合并employees表和contractors表中的namesalary列,并去除重复的行。如果有员工和承包商的姓名和薪资完全相同,那么在最终结果集中只会出现一次。

5.2 使用UNION ALL

sql 复制代码
SELECT name, salary
FROM employees
UNION ALL
SELECT name, salary
FROM contractors;

这个查询会合并两个表中的数据,包括重复的行。即使有员工和承包商的姓名和薪资完全相同,它们也会在结果集中分别出现。

6. 与其他操作符对比

6.1 与JOIN对比

JOIN用于根据两个或多个表之间的关联条件将它们的行组合在一起,通常用于获取来自多个表的相关数据。例如,通过JOIN可以将employees表和departments表关联起来,获取每个员工所在的部门信息。而UNION用于合并来自不同查询的结果集,这些查询可能基于不同的表或相同表的不同条件。简单来说,JOIN是横向连接数据,UNION是纵向合并数据。

6.2 与INTERSECT和EXCEPT对比

在一些数据库中,还存在INTERSECTEXCEPT操作符。INTERSECT用于返回两个查询结果集的交集,即同时存在于两个结果集中的行;EXCEPT用于返回在第一个查询结果集中但不在第二个查询结果集中的行。MySQL本身没有直接的INTERSECTEXCEPT操作符,但可以通过其他方式实现类似的功能。例如,可以使用IN子查询或JOIN操作来模拟INTERSECTEXCEPT的效果。

相关推荐
想摆烂的不会研究的研究生1 小时前
每日八股——Redis(1)
数据库·经验分享·redis·后端·缓存
码熔burning1 小时前
MySQL 8.0 新特性爆笑盘点:从青铜到王者的骚操作都在这儿了!(万字详解,建议收藏)
数据库·mysql
xiaolizi5674891 小时前
安卓远程安卓(通过frp与adb远程)完全免费
android·远程工作
阿杰100011 小时前
ADB(Android Debug Bridge)是 Android SDK 核心调试工具,通过电脑与 Android 设备(手机、平板、嵌入式设备等)建立通信,对设备进行控制、文件传输、命令等操作。
android·adb
猫头虎1 小时前
2025最新OpenEuler系统安装MySQL的详细教程
linux·服务器·数据库·sql·mysql·macos·openeuler
梨落秋霜1 小时前
Python入门篇【文件处理】
android·java·python
哈库纳玛塔塔2 小时前
放弃 MyBatis,拥抱新一代 Java 数据访问库
java·开发语言·数据库·mybatis·orm·dbvisitor
@LetsTGBot搜索引擎机器人3 小时前
2025 Telegram 最新免费社工库机器人(LetsTG可[特殊字符])搭建指南(含 Python 脚本)
数据库·搜索引擎·机器人·开源·全文检索·facebook·twitter
计算机毕设VX:Fegn08954 小时前
计算机毕业设计|基于springboot + vue动物园管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
冉冰学姐4 小时前
SSM校园排球联赛管理系统y513u(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·ssm 框架应用·开题报告、