Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > mysql union关键字

mysql中union关键字的实现示例

作者:哈里谢顿

本文主要介绍了mysql中的union关键字详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

MySQL 的 UNION 用于合并两个或多个 SELECT 语句的结果集,并自动去除重复行(相当于对结果集执行 DISTINCT)。

1. 基本语法与核心规则

SELECT column1, column2 FROM table1
UNION [ALL | DISTINCT]
SELECT column1, column2 FROM table2;

强制性规则

2. UNION vs UNION ALL

特性UNION (DISTINCT)UNION ALL
去重自动去重,行唯一保留所有行,包括重复
性能需要临时表+哈希排序去重,较慢直接追加结果,极快
使用场景必须确保唯一性时确定无重复或需要保留重复时

性能建议:除非业务需要去重,否则优先使用 UNION ALL。去重操作需要创建临时表、哈希比较和额外排序,大数据量时性能差距巨大。

3. 实际应用场景

场景 A:合并相似结构表(如分表)

-- 查询 2023 和 2024 年的订单(假设按年分表)
SELECT order_id, amount, created_at FROM orders_2023
UNION ALL
SELECT order_id, amount, created_at FROM orders_2024
ORDER BY created_at DESC
LIMIT 20;

场景 B:多维度统计报表

SELECT 'VIP用户' as user_type, COUNT(*) as cnt FROM users WHERE level >= 8
UNION ALL
SELECT '普通用户', COUNT(*) FROM users WHERE level BETWEEN 1 AND 7
UNION ALL
SELECT '访客', COUNT(*) FROM users WHERE level = 0;

场景 C:数据补全与兜底查询

-- 先查缓存表,若无结果再查主表(常见于配置表)
SELECT config_value FROM config_cache WHERE config_key = 'site_name'
UNION ALL
SELECT config_value FROM config WHERE config_key = 'site_name'
LIMIT 1;

4. 进阶用法

带排序和分页

(SELECT id, name FROM products WHERE category = 'A' ORDER BY price DESC LIMIT 10)
UNION ALL
(SELECT id, name FROM products WHERE category = 'B' ORDER BY price DESC LIMIT 10)
ORDER BY price DESC LIMIT 10;

注意:子查询中的 ORDER BY 必须配合 LIMIT 才生效,否则会被优化器忽略。

混合聚合与明细

SELECT city, sales_amount, NULL as detail FROM sales_summary
UNION ALL
SELECT city, amount, CONCAT(product_name, ':', quantity) FROM sales_detail;

5. 性能优化要点

  1. 索引利用:每个 SELECT 独立使用索引,UNION 本身不走索引
  2. 减少数据集:在子查询中先 WHERE 过滤,避免传递大量数据到 UNION 层
  3. 避免临时表写入UNION DISTINCT 会创建内存临时表(或磁盘临时表,若过大),可通过 SET tmp_table_size 调优
  4. 并行执行:MySQL 8.0.19+ 对非相关子查询的 UNION 可能启用并行查询

6. 常见陷阱

-- ❌ 错误:列数不匹配
SELECT id, name FROM t1
UNION
SELECT id FROM t2;  -- ERROR 1222

-- ❌ 错误:ORDER BY 位置错误
SELECT * FROM t1 ORDER BY id
UNION
SELECT * FROM t2;  -- ERROR 1221

-- ✅ 正确写法
SELECT * FROM t1
UNION
SELECT * FROM t2
ORDER BY id;  -- 使用第一个 SELECT 的列名排序

7. Django ORM 中的 UNION

如果你在使用 Django(看你之前关注过 Django 源码),可以这样使用:

from django.db.models import Q

# QuerySet.union() 默认使用 UNION ALL
qs1 = User.objects.filter(status='active').values('name', 'email')
qs2 = User.objects.filter(is_staff=True).values('name', 'email')

# UNION ALL
combined = qs1.union(qs2, all=True)

# UNION (去重)
combined_distinct = qs1.union(qs2)  # 或 all=False

注意:Django 的 union() 会强制转换为 SQL 的 UNION,且 QuerySet 被求值后返回的是列表而非 QuerySet,无法继续链式过滤。

总结UNION ALL 是合并结果集的高性能首选,UNION (DISTINCT) 仅在需要去重时使用。始终确保子查询列数一致,并在应用层处理复杂的排序逻辑。

到此这篇关于mysql中union关键字的实现示例的文章就介绍到这了,更多相关mysql union关键字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文