在MySQL的实际开发场景中,我们经常会遇到需要同时执行多条逻辑独立、没有关联条件的SQL语句,并且希望将这些查询的结果整合到同一个结果集返回的需求。比如需要同时统计不同表的数据量、查询不同维度的独立统计结果等,这些SQL之间因为没有共同的关联字段,无法直接通过JOIN操作合并,这时候就可以使用UNION或者UNION ALL操作符来实现多SQL结果的封装合并。

UNION和UNION ALL的基本用法
UNION和UNION ALL是MySQL中用于合并多个SELECT语句结果集的操作符,使用它们可以将多条独立的SQL查询结果拼接成一个结果集。两者的核心区别在于是否对合并后的结果进行去重处理。
UNION操作符
UNION会自动对合并后的结果集进行去重,并且会对最终的结果按照默认规则进行排序。基本语法格式如下:
-- 第一条独立查询SQL SELECT column1, column2 FROM table1 WHERE condition1 UNION -- 第二条独立查询SQL SELECT column3, column4 FROM table2 WHERE condition2 UNION -- 可以继续拼接更多独立查询SQL SELECT column5, column6 FROM table3 WHERE condition3;
需要注意的是,使用UNION合并的多个SELECT语句必须满足两个基本条件:一是每个SELECT语句返回的列数必须相同;二是对应位置的列的数据类型必须兼容,否则会抛出语法错误。
UNION ALL操作符
UNION ALL不会进行去重操作,也不会对结果进行排序,只是简单地将多个查询结果拼接在一起,因此执行效率比UNION更高。语法格式和UNION一致:
SELECT col1, col2 FROM t1 WHERE id > 10 UNION ALL SELECT col1, col2 FROM t2 WHERE status = 1 UNION ALL SELECT col1, col2 FROM t3 WHERE create_time > '2024-01-01';
实际场景示例
下面通过几个常见的开发场景来演示如何使用这两个操作符封装多条无关联SQL的结果。
场景1:统计不同表的独立数据量
假设我们需要同时统计用户表user的总数量、订单表order的总数量、商品表product的总数量,这三个查询之间没有关联条件,就可以用如下SQL实现:
-- 统计用户总数 SELECT '用户总数' AS stat_type, COUNT(*) AS stat_value FROM user UNION ALL -- 统计订单总数 SELECT '订单总数' AS stat_type, COUNT(*) AS stat_value FROM order UNION ALL -- 统计商品总数 SELECT '商品总数' AS stat_type, COUNT(*) AS stat_value FROM product;
执行上述SQL后,会得到一个包含三行数据的结果集,每一行对应一个统计类型的数值,实现了多条无关联统计SQL的结果合并。
场景2:查询不同维度的独立数据
如果需要同时查询本月新增的用户ID列表、本月售出的商品ID列表,这两个结果集没有关联字段,也可以合并返回:
-- 查询本月新增用户ID SELECT user_id, '新增用户' AS data_type FROM user WHERE MONTH(create_time) = MONTH(NOW()) UNION ALL -- 查询本月售出商品ID SELECT product_id AS user_id, '售出商品' AS data_type FROM order_detail WHERE MONTH(order_time) = MONTH(NOW());
这里通过增加data_type列来区分不同来源的数据,方便后续业务处理时识别每条记录的归属。
使用注意事项
- 合并的多个SELECT语句返回的列数必须完全一致,如果某条SQL返回的列数较少,可以用NULL填充对应的列,例如:SELECT col1, col2, NULL AS col3 FROM t1 UNION ALL SELECT col1, col2, col3 FROM t2。
- 如果需要对合并后的整个结果集进行排序,只能在最后一条SELECT语句之后添加ORDER BY子句,不能在每个独立的SELECT语句后单独加ORDER BY,除非每个SELECT语句用括号包裹。
- 如果需要给合并后的结果集添加总排序,且使用的是UNION操作符,由于UNION本身会排序,可能需要注意排序逻辑的冲突;如果不需要去重,优先使用UNION ALL提升性能。
- 当合并的SQL中存在字符串类型的列时,需要注意字符集和排序规则一致,否则可能出现合并异常。
总结
对于无法关联的多条SQL,通过UNION或UNION ALL操作符可以很方便地封装到同一个结果集中。如果确认多个查询结果之间没有重复数据,或者不需要去重,优先选择UNION ALL来获得更好的执行效率。使用时只要保证每个SELECT语句的列数和数据类型兼容,就可以灵活实现多独立SQL结果的合并,满足业务上一次性获取多维度数据的需求。