8

我试图将此解决方案应用于我在 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脚本会产生循环过程,但是这里我其实没看到有什么相关的——很明显forDELETE和for的两个选择SELECT是分离的——引擎必须先做SELECT 一次,然后在WHERE条件for中使用DELETE。那么 - 为什么会发生这个错误,我如何才能真正删除我的表?=)

4

5 回答 5

28

试试这个可能对你有帮助

DELETE  FROM NAME
WHERE NAME.id NOT IN (
                     SELECT * FROM ( 
                                    SELECT MIN(id)  FROM NAME GROUP BY col1,col2
                                   ) AS p 
                      ) 

阅读更多

于 2013-07-19T09:10:50.190 回答
4

您的查询是正确的,并且可以在其他 DBMS 上运行,但是 MySQL 不允许您从表中更新或删除,并在子查询中从同一个表中进行选择。它记录在官方DELETE文档中。

它可能会在未来的版本中修复,但目前不支持您的查询。

一个简单的解决方法是将您的子查询放在子子查询中,例如 echo_Me 答案:

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

小提琴在这里

于 2013-07-21T16:23:13.643 回答
3

来自手册
“目前,您无法从表中删除并在子查询中从同一个表中选择。”

使用适当的数据库引擎,或单独运行查询。(以编程方式存储 id,介于两者之间。)

于 2013-07-19T09:17:55.753 回答
0

如果要从表中删除记录,请使用DELETE FROM tablename. 您不能在此处指定列。如果要从列中删除数据,请使用 UPDATE 语句将列的值设置为空白或 NULL。

于 2013-07-19T09:16:49.740 回答
-1

删除的语法

不需要列的名称

因为mysql删除所有满足条件的数据

于 2013-07-19T09:18:57.547 回答