การสลับ (Swap) ค่าระหว่างสองแถวในคอลัมน์เดียวด้วย CASE WHEN
เมื่อต้องการสลับค่าของสองแถวเฉพาะในคอลัมน์เดียว (ไม่ใช่สลับคอลัมน์) ใช้ CASE WHEN ภายในคำสั่ง UPDATE
สร้างตารางและข้อมูล
mysql> create table DemoTable1382 (
-> StudentName varchar(20)
-> );
Query OK, 0 rows affected (0.57 sec)
mysql> insert into DemoTable1382 values('John');
mysql> insert into DemoTable1382 values('Chris');
mysql> insert into DemoTable1382 values('Adam');
mysql> insert into DemoTable1382 values('Bob');
ข้อมูลก่อนสลับ
+-------------+ | StudentName | +-------------+ | John | | Chris | | Adam | | Bob | +-------------+
คำสั่ง UPDATE สลับ John และ Chris
mysql> update DemoTable1382
-> set StudentName = (
-> case
-> when StudentName = 'Chris' then 'John'
-> when StudentName = 'John' then 'Chris'
-> else StudentName
-> end
-> );
Query OK, 2 rows affected (0.19 sec)
Rows matched: 4 Changed: 2 Warnings: 0
ข้อมูลหลังสลับ
+-------------+ | StudentName | +-------------+ | Chris | | John | | Adam | | Bob | +-------------+
หลักการทำงาน
- MySQL ประเมิน
CASEแบบลำดับ (sequential) — ตรงเงื่อนไขไหนก่อนใช้เงื่อนไขนั้น - เงื่อนไข
when StudentName = 'Chris' then 'John'รันก่อน: แถว Chris กลายเป็น John - จากนั้น
when StudentName = 'John' then 'Chris': แถว John เดิม (และแถว Chris ที่เพิ่งเปลี่ยน) จะกลายเป็น Chris — แต่ MySQL ใช้ค่าเดิมของแถวในการประเมินทุก WHEN จึงทำงานถูกต้อง else StudentName— คงค่าเดิมสำหรับแถวอื่น
วิธีอื่น: ใช้ตัวแปรชั่วคราว (สำหรับสลับคอลัมน์)
หากต้องการสลับค่าระหว่างสอง คอลัมน์ (ไม่ใช่แถว):
UPDATE t SET a = @tmp := a, a = b, b = @tmp;
หรือใน MySQL 8.0+ ใช้ CTE:
WITH swapped AS (
SELECT id, b AS a, a AS b FROM t
)
UPDATE t JOIN swapped USING (id) SET t.a = swapped.a, t.b = swapped.b;
ข้อควรระวัง: คำสั่ง UPDATE แบบ CASE WHEN นี้ทำงานได้เพราะ MySQL ใช้ค่าเดิม (original values) ในการประเมินทุก WHEN clause ภายในแถวเดียวกัน ไม่ได้ใช้ค่าที่เพิ่งอัปเดตไปแล้ว