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

相关推荐
tant1an32 分钟前
MySQL面试题(一)
数据库·mysql
喜欢的名字被抢了1 小时前
MongoDB生产实践:架构设计、分片集群与运维监控
数据库·mongodb·教程
红糖奶茶1 小时前
MySQL 8.0的自增主键持久化特性
数据库·mysql·adb
Macbethad2 小时前
基于TwinCAT的半导体刻蚀设备SCADA管理程序技术方案
运维·网络·数据库
ai_coder_ai2 小时前
编写自动化脚本,在自己后端服务中使用云原生Baas服务进行设备相关操作
数据库·云原生·自动化
oradh2 小时前
Oracle DG主备架构的基本维护操作总结
数据库·oracle·架构·dg主备架构的基本维护操作总结
xieliyu.3 小时前
MySQL 六大基础约束详解:NOT NULL/DEFAULT/UNIQUE/ 主键 / 外键 / CHECK
android·数据库·sql·mysql
Anokata3 小时前
MYSQL SQL 执行系列1
android·sql·mysql
JSON_L4 小时前
MongoDB文档关系详解
数据库·mongodb
卓怡学长4 小时前
w268基于springboot + vue 物流系统
java·数据库·vue.js·spring boot·spring·intellij-idea