MySQLでUPDATEするときの列順とその影響

MySQLのUPDATE文でSET col1 = col1 + 1, col2 = co1としたとき、col2 = col1col1は更新前の値ではなくて更新後の値が用いられる。

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にどのような値が入ってほしいかに関わらず、col2col1の値をもとに決まる以上、常にcol2col1よりも前に更新するようにした方が、読みやすいSQLになり、バグにも繋がりにくくなる。