Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

MySQL: อัปเดตตารางโดยสลับค่าของสองแถวด้วย CASE WHEN

การสลับ (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 ภายในแถวเดียวกัน ไม่ได้ใช้ค่าที่เพิ่งอัปเดตไปแล้ว