首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 互換表中兩列數據的正確姿勢:自連接 UPDATE 避開賦值順序陷阱

     編輯:MySQL 資料庫相關知識

一、 業務場景

表 product(id, name, original_price, price) 需將「原價」與「現價」兩列數值互換。

二、 錯誤示範:順序賦值導致數據丟失

UPDATE product SET original_price = price, price = original_price;

執行流程:

  1. original_price = price → 原價列覆蓋為現價值
  2. price = original_price → 此時 original_price 已是新值,相當於 price = price,**現價列不變**

結果:兩列均變為原現價值,**原價數據永久丟失**。

三、 正確寫法:自連接 UPDATE

UPDATE product AS a
INNER JOIN product AS b ON a.id = b.id
SET a.original_price = b.price,
    a.price = b.original_price;

原理:將同一表作為兩個別名 a、b 參與連接,SET 子句同時讀取 b 的舊值寫入 a,互不干擾。等效於「快照讀取 → 批量寫入」。

四、 替代方案對比

方案SQL優點缺點
自連接 UPDATEUPDATE t a JOIN t b ON a.id=b.id SET a.x=b.y, a.y=b.x單條語句、原子性、無臨時對象大表鎖表時間長
臨時變量UPDATE t SET x=@tmp:=x, x=y, y=@tmp無自連接開銷依賴變量求值順序,版本間行為可能不一致,不推薦
中間表CREATE TEMP TABLE tmp AS SELECT id, y AS new_x, x AS new_y FROM t; UPDATE t JOIN tmp ...大表分批提交、可中斷恢復需額外存儲、多步驟
應用層讀改寫SELECT → 交換 → 批量 UPDATE業務邏輯可控、易測試網絡往返、併發衝突風險

五、 擴展:多列循環移位

若需 a→b, b→c, c→a 三列循環:

UPDATE t AS a
JOIN t AS b ON a.id = b.id
SET a.col1 = b.col2,
    a.col2 = b.col3,
    a.col3 = b.col1;

六、 總結

MySQL UPDATE 多列賦值**按書寫順序依次執行**,直接互換會導致數據覆蓋。**自連接 UPDATE** 是標準、安全、單語句解法:UPDATE t a JOIN t b ON a.pk=b.pk SET a.col1=b.col2, a.col2=b.col1。大表操作建議分批次(按主鍵範圍)執行,或維護窗口期執行,避免長事務阻塞業務。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved