我试图将this解决方案应用于MySQL DB中具有重复项的表中的数据。我得到了这样的错误:
SQL Error [1093] [HY000]: You can't specify target table 'NAME' for update in FROM clause
DELETE NAME FROM NAME
WHERE NAME.id NOT IN
(SELECT MIN(id)
FROM NAME GROUP BY col1, col2)
也尝试过分配别名 - 但没有成功。
这个错误的原因是什么?
它通常指出SQL脚本可以产生循环过程,但在这里我实际上没有看到与此相关的任何内容 - 很明显,DELETE
和SELECT
的两个选择是分离的 - 引擎必须{{1首先,然后在SELECT
条件WHERE
中使用它。
那么 - 为什么会发生这种错误,我怎样才能实际删除我的表格? =)
答案 0 :(得分:27)
试试这可能会对你有所帮助
DELETE FROM NAME
WHERE NAME.id NOT IN (
SELECT * FROM (
SELECT MIN(id) FROM NAME GROUP BY col1,col2
) AS p
)
答案 1 :(得分:4)
您的查询是正确的,可以在其他DBMS上运行,但MySQL不允许您从表中更新或删除,并从子查询中的同一个表中进行选择。它记录在官方DELETE文档中。
可能会在将来的版本中修复,但目前不支持您的查询。
一个简单的解决方法是将子查询放在子子查询中,例如echo_Me answer:
WHERE NAME.id NOT IN (SELECT * FROM (your subquery) s)
这将强制MySQL使用子查询的结果创建一个临时表,并且由于您实际上不是从同一个表中选择,而是从临时表中选择,因此该查询将正常运行。但是,表现可能很差。
您通常使用联接来消除错误#1093。这是您在联接表单中的查询:
DELETE NAME
FROM
NAME LEFT JOIN (
SELECT col1, col2, MIN(id) min_id
FROM NAME
GROUP BY col1, col2) s
ON (NAME.col1, NAME.col2, NAME.id) = (s.col1, s.col2, s.min_id)
WHERE
s.min_id IS NULL
或者您可以使用这个更简单的版本,它应该是最快的版本:
DELETE N1
FROM
NAME N1 INNER JOIN NAME N2
ON
N1.col1=N2.COL1
AND N1.col2=N2.col2
AND N1.ID > N2.ID
小提琴是here。
答案 2 :(得分:3)
From the manual:
"目前,您无法从表中删除并从子查询中的同一个表中进行选择。"
使用适当的数据库引擎,或单独运行查询。 (以编程方式存储id,介于两者之间。)
答案 3 :(得分:0)
如果要删除表中的记录,请使用DELETE FROM tablename
。您无法在此处指定列。如果要从列中删除数据,请使用UPDATE语句将列的值设置为空或NULL。
答案 4 :(得分:-1)
delete 的语法不需要列的名称
因为mysql会删除满足条件的所有数据