Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Sửa lỗi ERROR 1093: Không thể UPDATE/DELETE bảng đang SELECT trong subquery MySQL

MySQL không cho phép sửa đổi (UPDATE/DELETE) một bảng mà đồng thời SELECT từ bảng đó trong subquery (derived table). Lỗi: ERROR 1093 (HY000): You can't specify target table for update in FROM clause.

Ví dụ gây lỗi

DELETE FROM DemoTable1597 
WHERE Marks = (SELECT MIN(Marks) FROM DemoTable1597);

Giải pháp: Bọc subquery thêm 1 lớp (derived table)

MySQL cho phép nếu subquery được wrap trong một derived table khác:

DELETE FROM DemoTable1597
WHERE Marks = (
    SELECT lowestMarks FROM (
        SELECT MIN(Marks) AS lowestMarks FROM DemoTable1597
    ) AS deleteRecord
) LIMIT 1;

Ví dụ minh họa

Tạo bảng và chèn dữ liệu:

CREATE TABLE DemoTable1597 (Marks INT);
INSERT INTO DemoTable1597 VALUES (45), (59), (43), (85), (89);

Xóa giá trị nhỏ nhất (43):

DELETE FROM DemoTable1597
WHERE Marks = (
    SELECT lowestMarks FROM (
        SELECT MIN(Marks) AS lowestMarks FROM DemoTable1597
    ) AS deleteRecord
) LIMIT 1;

Kết quả

Marks (còn lại)
45
59
85
89

Giải thích

  • Subquery trong ngoặc vuông (SELECT MIN(Marks) ...) tạo derived table tạm thời.
  • Outer subquery SELECT lowestMarks FROM (...) AS deleteRecord "materializes" kết quả → MySQL cho phép UPDATE/DELETE bảng gốc.
  • LIMIT 1: Chỉ xóa 1 hàng nếu có nhiều hàng cùng giá trị min.

Các cách khác

1. Multi-table DELETE (JOIN)

DELETE d1 FROM DemoTable1597 d1
JOIN (SELECT MIN(Marks) AS min_mark FROM DemoTable1597) d2
  ON d1.Marks = d2.min_mark
LIMIT 1;

2. MySQL 8.0+: CTE

WITH min_mark AS (SELECT MIN(Marks) AS m FROM DemoTable1597)
DELETE FROM DemoTable1597 WHERE Marks = (SELECT m FROM min_mark) LIMIT 1;

3. Ứng dụng: SELECT trước, DELETE sau (2 truy vấn)

SELECT MIN(Marks) INTO @min_mark FROM DemoTable1597;
DELETE FROM DemoTable1597 WHERE Marks = @min_mark LIMIT 1;

Khuyên dùng: Cách bọc derived table (wrapper) đơn giản, tương thích mọi phiên bản MySQL.