SQL的update语句更新顺序的坑

文章目录

环境

  • Windows 11 专业版
  • XAMPP v3.3.0
    • MySQL Ver 15.1
  • MySQL Workbench 8.0 CE

背景

t1 中有三列 c1c2c3

  • c1 :总名额
  • c2 :已报名数量
  • c3 :替补名额

其中,"总名额"包含了"替补名额"。比如,一场比赛A(id为1)的正式名额是14,而总名额是20,其中包含了6个替补名额。到报名截止时间,实际报名数量是18人。也就是说:

  • c1 = 20
  • c2 = 18
  • c3 = 6

t1 如下:

在比赛开始前,需要处理替补人员。对于本例,只有14个正式名额,因此需要把4个替补人员劝退( c2 会变成14)。

接下来,需要把替补名额修改为0,并把总名额修改为14。

SQL

从上面的需求可知,对于"把替补名额修改为0,并把总名额修改为14",只需要一个update语句,把 c3 清零,并把 c1 改为 c1 - c3

sql 复制代码
update t1 set c3 = 0, c1 = c1 - c3 where id = 1;

看上去没有问题,然而,运行SQL后,表 t1 内容如下:

可见, c1 的值没有变化!

这是因为,update语句在更新数据时,按照"从左到右"的顺序依次更新,并且使用的是"最新的值"。

也就是说,我们期望把 c1 修改为 c1 - c3 ,也就是 20 - 6 ,值为 14 ,然而,在此操作之前, c3 已经被清零了,所以, c1 的值实际上并没有发生变化。

这个问题让我困惑了半天,我一直以为是我把SQL语句哪里写错了(因为我使用了ThinkPHP框架,没有用原生SQL),后来才醒悟过来,是我对SQL的语义理解有偏差。

知道了问题产生的原因,那么问题也就迎刃而解了。

最简单的解决办法,就是交换一下更新的顺序:

sql 复制代码
update t1 set c1 = c1 - c3, c3 = 0 where id = 1;

这样, c1c3 都能得到期望值了。

总结

update语句在更新数据时,按照"从左到右"的顺序依次更新,并且使用的是"最新的值",所以一定要小心顺序,别搞错了。

相关推荐
rising start2 小时前
二、全面理解MySQL架构
mysql·架构
星星也在雾里2 小时前
PgBouncer 解决 PostgreSQL 连接数超限 + 可视化监控
数据库·postgresql
bqq198610263 小时前
MySQL性能优化
mysql·mysql优化
雨辰AI4 小时前
SpringBoot3 + 人大金仓读写分离 + 分库分表 + 集群高可用 全栈实战
java·数据库·mysql·政务
长城20244 小时前
关于MySql的ONLY_FULL_GROUP_BY问题
数据库·mysql·聚合列
常常有5 小时前
MySQL 底层执行原理:输入SQL语句到两阶段提交
数据库·sql·mysql
Mr. zhihao5 小时前
深入解析redis基本数据结构
数据结构·数据库·redis
m0_748839495 小时前
利用天正暖通CAD快速掌握风管数量统计的方法
数据库
随身数智备忘录5 小时前
什么是设备管理体系?设备管理体系包含哪些核心模块?
网络·数据库·人工智能
海市公约6 小时前
MySQL更新语句执行全流程:从Buffer Pool修改到二阶段提交
数据库·mysql·binlog·innodb·undo log·二阶段提交·update执行原理