文章目录
环境
- Windows 11 专业版
- XAMPP v3.3.0
- MySQL Ver 15.1
- MySQL Workbench 8.0 CE
背景
表 t1 中有三列 c1 、 c2 和 c3 :
c1:总名额c2:已报名数量c3:替补名额
其中,"总名额"包含了"替补名额"。比如,一场比赛A(id为1)的正式名额是14,而总名额是20,其中包含了6个替补名额。到报名截止时间,实际报名数量是18人。也就是说:
c1= 20c2= 18c3= 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;
这样, c1 和 c3 都能得到期望值了。

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