MySQL union的一个坑

文章讨论了SQL查询中UNION和UNIONALL的区别,指出UNION会去除重复记录导致结果不正确(如1重复计为2),而UNIONALL则保留所有记录。解决办法是使用UNIONALL以获得预期的6的结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看以下的SQL:

SELECT sum(`1`) FROM
(SELECT 1 from DUAL
UNION
SELECT 1 from DUAL
UNION
SELECT 2 from DUAL
UNION
SELECT 3 from DUAL) as t

执行的结果是什么?

开始以为是:7;但是事实是:6。

原因是:1重复了一次,Union将其合并为一条记录。

解决方法:使用Union All替换。

SELECT sum(`1`) FROM
(SELECT 1 from DUAL
UNION ALL
SELECT 1 from DUAL
UNION ALL
SELECT 2 from DUAL
UNION ALL
SELECT 3 from DUAL) as t

<think>嗯,用户想了解MySQL8.0与其他版本的差异,特别是和5.7版本的对比。从引用内容看,用户已经提供了一些参考资料,包括8.0的新特性、升级注意事项以及性能对比信息。用户应该是数据库管理员或开发者,正在评估是否要升级到8.0。用户可能真正关心的是实际业务影响:升级的收益是否大于风险?是否需要重构代码?性能提升是否显著?尤其是看到引用3中提到PostgreSQL在点查上碾压MySQL,可能还隐含了选型考量。不过当前问题聚焦在MySQL内部版本对比,需要优先解决这个核心问题。梳理差异时要注意层次:功能改进(窗口函数/CTE/JSON)、性能优化(索引/直方图)、安全增强(认证/密码策略)、行为变更(默认字符集/严格模式)。特别要强调升级点,比如用户认证插件变更这种可能导致业务中断的关键点。需要提醒8.0虽然官方宣称性能提升,但引用3显示特定场景可能不如PostgreSQL,如果用户有高频点查需求,这点值得展开。不过当前问题限定在MySQL版本对比,PostgreSQL部分只需简单提及。最后要区分“新项目”和“升级现有系统”两种场景给出建议。用户没明说当前版本,但引用1、2都聚焦5.7到8.0的升级路径,回复应该覆盖测试策略和回滚预案。</think> 以下是MySQL 8.0与其他版本(特别是MySQL 5.7)的核心差异对比,按关键维度分类说明: --- ### **一、功能性升级** 1. **窗口函数(Window Functions)** - MySQL 8.0支持`ROW_NUMBER()`, `RANK()`, `LEAD()`等分析函数,简化复杂查询(如分组排名) - **对比**:MySQL 5.7需通过复杂自连接实现[^1] 2. **公用表表达式(CTE)** - 支持递归查询(如树形结构数据处理): ```sql WITH RECURSIVE cte AS ( SELECT id, parent_id FROM items WHERE id=1 UNION ALL SELECT items.id, items.parent_id FROM items JOIN cte ON items.parent_id=cte.id ) SELECT * FROM cte; ``` - **对比**:MySQL 5.7需依赖临时表或存储过程[^1] 3. **JSON增强** - 新增`JSON_TABLE()`, `JSON_ARRAYAGG()`等20+函数 - 支持JSON部分更新(仅修改指定路径数据,降低存储开销)[^1] --- ### **二、性能优化** | **特性** | **MySQL 8.0** | **MySQL 5.7** | |-------------------|----------------------------------------|-------------------------------| | **降序索引** | 支持`DESC`索引(优化ORDER BY ... DESC)| 实际按升序索引反向扫描 | | **直方图统计** | 基于数据分布优化查询计划 | 仅依赖索引统计信息[^1] | | **资源组管理** | 可分配CPU核心限制SQL线程优先级 | 不支持 | --- ### **三、安全与稳定性** 1. **认证插件变更** - 默认认证插件从`mysql_native_password`改为`caching_sha2_password` - **影响**:旧客户端需更新驱动(如PHP需升级至7.4+)[^2] 2. **原子DDL操作** - 表结构变更(ALTER TABLE)支持原子性,崩溃后自动回滚 - **对比**:MySQL 5.7可能遗留中间状态文件[^1] 3. **密码策略增强** - 支持密码历史管理、双密码机制、随机密码生成 --- ### **四、兼容性与行为变更** | **配置项** | **MySQL 8.0** | **MySQL 5.7** | |----------------------|---------------------------|------------------------| | **默认字符集** | `utf8mb4`(支持4字节表情)| `latin1` | | **严格模式** | 默认开启(如日期零值报错)| 默认关闭[^2] | | **系统表存储引擎** | 全部采用InnoDB | 部分使用MyISAM | --- ### **五、升级建议** 1. **推荐升级场景** - 新项目优先选用8.0(性能提升达**2-5倍**,尤其在读写混合场景) - 需使用JSON深度处理或分析型SQL的业务 2. **谨慎升级场景** - 旧系统需验证兼容性: ```sql -- 检查认证插件冲突 SELECT user, plugin FROM mysql.user WHERE plugin='mysql_native_password'; ``` - 测试严格模式影响(如零值日期、GROUP BY非聚合列)[^2] --- ### **与PostgreSQL的对比参考** - **点查性能**:PostgreSQL 15在单行查询场景比MySQL 8.0快**30-50%**(索引优化更高效)[^3] - **复杂查询**:MySQL 8.0的窗口函数性能接近PostgreSQL,但递归查询优化仍存差距 --- **推荐行动路径**: 1. 使用`mysql_upgrade`工具检测兼容性问题 2. 在测试环境启用`--upgrade=FORCE`模拟升级 3. 关键业务配置回滚方案(如备份+二进制日志保留)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值