MySQL 不允許直接在 DELETE 的子查詢中引用同一張表,會報錯 You can't specify target table for update in FROM clause。本文揭秘多層嵌套+別名繞過限制的核心模式。
DELETE FROM target_table
WHERE id IN (
SELECT id FROM (
SELECT MIN(id) AS id
FROM target_table
GROUP BY duplicate_column
HAVING COUNT(*) > 1
) AS alias_name
);
MIN(id) 保留最早記錄,HAVING COUNT(*) > 1 篩選重複組。AS alias_name),將結果物質化為派生表,打破「同表更新查詢」限制。DELETE ... WHERE id IN (...) 精準刪除標記的重複行。DELETE FROM articles
WHERE id IN (
SELECT id FROM (
SELECT MIN(id) AS id
FROM articles
GROUP BY title
HAVING COUNT(*) > 1
) AS dup_ids
);
DELETE FROM articles
WHERE id IN (
SELECT id FROM (
SELECT MAX(id) AS id
FROM articles
GROUP BY title
HAVING COUNT(*) > 1
) AS dup_ids
);
LIMIT 1000 循環執行,避免長事務鎖表。JOIN DELETE。ROW_NUMBER() 窗口函數 (MySQL 8.0+) 更優雅:WITH ranked AS (
SELECT id, ROW_NUMBER() OVER (PARTITION BY title ORDER BY id) AS rn
FROM articles
)
DELETE FROM articles WHERE id IN (SELECT id FROM ranked WHERE rn > 1);