MySQLでUPDATEするときの列順とその影響
MySQLのUPDATE文でSET col1 = col1 + 1, col2 = co1
としたとき、col2 = col1
のcol1
は更新前の値ではなくて更新後の値が用いられる。
MySQL のドキュメントに明記されていることだが、標準SQLと異なっており、注意をしなければならない。(最新のMySQL 8でも一緒)
次のステートメントの 2 番目の割り当ては、col2 を元の col1 値ではなく、現在の (更新された) col1 値に設定します。この結果、col1 と col2 の値が同じになります。この動作は標準 SQL とは異なります。
UPDATE t1 SET col1 = col1 + 1, col2 = col1;
カラムの順序を入れ替える
MySQLの仕様は把握した上で、実装ルールとしてはSET
で更新するカラムを、それ以降参照しないようにすべき。
UPDATE t1 SET col1 = col1 + 1, col2 = col1;
であれば1番目と2番目を入れ替えれば良い。
# 更新後のcol1, col2が同じになってほしいなら
UPDATE t1
SET col2 = col1 + 1,
col1 = col1 + 1;
# col2には更新前のcol1になってほしいなら
UPDATE t1
SET col2 = col1,
col1 = col1 + 1;
## if文などでも一緒
# col2が更新後のcol1の値次第で不変orNULLに分岐するなら
UPDATE t1
SET col2 = if(col1 - 1 > 0, col2, null)
col1 = col1 - 1;
# col2が更新前のcol1の値次第で不変orNULLに分岐するなら
UPDATE t1
SET col2 = if(col1 > 0, col2, null)
col1 = col1 - 1;
col2
にどのような値が入ってほしいかに関わらず、col2
がcol1
の値をもとに決まる以上、常にcol2
をcol1
よりも前に更新するようにした方が、読みやすいSQLになり、バグにも繋がりにくくなる。