2013-07-19 96 views
8

我试图将this解决方案应用于MySQL DB中具有重复项的表中的数据。我得到这样的错误:您无法在FROM子句中指定目标表'名称'进行更新

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脚本可以产生循环过程,但在这里我实际上没有看到任何与此有关的 - 很显然,DELETESELECT的两个选择是分离的 - 引擎必须首先执行SELECT,然后在WHERE条件中使用它为DELETE。 所以 - 为什么会发生这种错误,我怎么能真正重复删除我的表? =)

+1

您的查询看起来与您尝试应用的解决方案的查询完全无关。他们使用连接,而您正在使用'NOT IN'。 – eggyal

+0

@eggyal我的链接指向评论,而不是回答 –

+0

啊,够公平的;我没有注意到这一点。该评论是特定于SQL Server的。你会发现答案中给出的连接将在MySQL中工作。 – eggyal

回答

27

尝试这可能会帮助你

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

Read more

+0

@GillBates检查我更新的答案 –

+0

哇 - 非显而易见的解决方案!有效! –

+0

你欢迎:),很好,它为你工作! –

0

如果你想从一个表使用DELETE FROM tablename删除记录。你不能在这里指定一个列。如果要从列中删除数据,请使用UPDATE语句将列的值设置为空或NULL。

3

From the manual
“目前,您无法从表中删除并从子查询中的同一个表中进行选择。”

使用适当的数据库引擎,或单独运行查询。 (保存ID的编程方式,在两者之间。)

+0

你能举个例子吗? – Tarik

+1

一个合适的数据库? PostgreSQL的。 – aib

-1

的删除

的sintax不需要列

的名字,因为MySQL的删除符合条件的所有数据

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 

小提琴是here

相关问题