LoginSignup
4
1

More than 1 year has passed since last update.

MySQLで値の入れ替えをしたい

Posted at

カラムXとカラムYの値を入れ替えたい

ひょんなことからあるテーブルについてカラムXとカラムYに入っている値を入れ替えなければならなくなったとします。
そんなとき、安易に

UPDATE `table`
SET `X` = `Y`
  , `Y` = `X`;

とやろうとすると…地獄を見ます。
MySQLでは記述された順番に処理を実行するので、どちらも元のYの値で更新されてしまいます。
そこでちょっと一工夫必要です。

対応方法

1. ユーザー変数を使う

ググると解決策として多く出てきますね。(主観)
以下のサイトを参考にさせていただきました。
MySQLでフィールドの値を交換する

SET @temp = 0;
UPDATE `table`
SET `X` = (@temp:=`X`) * 0 + `Y`
  , `Y` = @temp;

数値型の場合ですね。
Xに代入するところで、変数@tempにも格納しつつ、ゼロ倍してそのままYの値が入るようにすると。
これはなかなか自力でたどり着けない解法でした。

2. 加減算/結合分割で処理する

以下のサイトを参考にさせていただきました。
MySQLで値の交換

#数値の場合
UPDATE `table`
SET `X` = `X` + `Y`
  , `Y` = `X` - `Y`
  , `X` = `X` - `Y`;

#文字列の場合
UPDATE `table`
SET `X` = CONCAT(`X`, ':', `Y`)
  , `Y` = SUBSTRING_INDEX(`X`, ':', 1)
  , `X` = SUBSTRING_INDEX(`X`, ':', -1);

①まずXに合計(結合)した値を格納し、
Yには合計からYを差し引いて元のXの値を格納、
③そして改めてXには合計から入れ替え後のY=元のXを差し引き、元のYの値を格納すると。
プログラムチックで、ある意味馴染みやすい解法でした。

3. 自己結合を使う

他であまり見つからなかったのですが、こんな方法も。

UPDATE `table` t1, `table` t2
SET t1.`X` = t2.`Y`
  , t1.`Y` = t2.`X`
WHERE t1.id = t2.id;

自己結合を使うと、冒頭の安易なSQLに近い形で実現できます。
結構シンプルですね。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1