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

แก้ ERROR 1093: You can't specify target table for update in FROM clause เมื่อ DELETE ค่าต่ำสุด

Error 1093 เกิดเมื่อพยายาม DELETE จากตารางเดียวกับที่ใช้ใน Subquery ตรงทางแก้คือ wrap Subquery อีกชั้นหนึ่ง (Derived Table)

ตัวอย่างปัญหา

สร้างตารางคะแนน:

mysql> create table DemoTable1597 (
    -> Marks int
    -> );
Query OK, 0 rows affected (0.69 sec)

เพิ่มข้อมูล:

mysql> insert into DemoTable1597 values(45),(59),(43),(85),(89);

ดูข้อมูล:

mysql> select * from DemoTable1597;
+-------+
| Marks |
+-------+
|    45 |
|    59 |
|    43 |
|    85 |
|    89 |
+-------+
5 rows in set (0.00 sec)

คิวรีที่ทำให้ Error 1093 (ผิด)

-- จะ Error: You can't specify target table 'DemoTable1597' for update in FROM clause
DELETE FROM DemoTable1597 WHERE Marks = (SELECT MIN(Marks) FROM DemoTable1597);

คิวรีที่แก้ไขแล้ว (ถูกต้อง)

mysql> delete from DemoTable1597 
    -> where Marks = (
    ->   select lowestMarks from (
    ->     select min(Marks) as lowestMarks from DemoTable1597
    ->   ) as deleteRecord
    -> ) limit 1;
Query OK, 1 row affected (0.11 sec)

ตรวจสอบผลลัพธ์ (ค่า 43 ถูกลบ):

mysql> select * from DemoTable1597;
+-------+
| Marks |
+-------+
|    45 |
|    59 |
|    85 |
|    89 |
+-------+
4 rows in set (0.00 sec)

คำอธิบายเทคนิค

  • Subquery ชั้นใน (select min(Marks) as lowestMarks from DemoTable1597) คำนวณค่าต่ำสุด
  • Subquery ชั้นนอก (select lowestMarks from ... ) as deleteRecord สร้าง Derived Table ชั่วคราว
  • MySQL จึงไม่เห็นว่าเป็นการอ้างอิงตารางเดียวกันโดยตรง จึงผ่านได้
  • LIMIT 1 ป้องกันลบหลายแถวถ้ามีค่าต่ำสุดซ้ำกัน

หมายเหตุ: MySQL 8.0+ รองรับ CTE (WITH clause) ทำให้อ่านง่ายกว่า