MySQL以子查询作为条件删除FROM

我试图做这样的查询:

DELETE FROM term_hierarchy AS th WHERE th.parent = 1015 AND th.tid IN ( SELECT DISTINCT(th1.tid) FROM term_hierarchy AS th1 INNER JOIN term_hierarchy AS th2 ON (th1.tid = th2.tid AND th2.parent != 1015) WHERE th1.parent = 1015 ); 

正如你可能知道,如果同一个tid有其他父母,我想删除父母关系到1015。 但是,这给我一个语法错误:

 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS th WHERE th.parent = 1015 AND th.tid IN ( SELECT DISTINCT(th1.tid) FROM ter' at line 1 

我已经检查了文档,并自己运行子查询,这似乎都看看。 谁能弄清楚这里有什么问题?

更新 :如下面的回答,MySQL不允许在子查询中使用你正在删除的表。

您不能指定目标表进行删除。

解决方法

 create table term_hierarchy_backup (tid int(10)); <- check data type insert into term_hierarchy_backup SELECT DISTINCT(th1.tid) FROM term_hierarchy AS th1 INNER JOIN term_hierarchy AS th2 ON (th1.tid = th2.tid AND th2.parent != 1015) WHERE th1.parent = 1015; DELETE FROM term_hierarchy AS th WHERE th.parent = 1015 AND th.tid IN (select tid from term_hierarchy_backup); 

对于其他人发现这个问题,希望在使用子查询时删除,我离开你这个超越MySQL的例子(即使有些人似乎认为它不能完成):

 DELETE e.* FROM tableE e WHERE id IN (SELECT id FROM tableE WHERE arg = 1 AND foo = 'bar'); 

会给你一个错误:

 ERROR 1093 (HY000): You can't specify target table 'e' for update in FROM clause 

但是这个查询:

 DELETE e.* FROM tableE e WHERE id IN (SELECT id FROM (SELECT id FROM tableE WHERE arg = 1 AND foo = 'bar') x); 

将工作得很好:

 Query OK, 1 row affected (3.91 sec) 

把你的子查询包装在一个额外的子查询(这里命名为x)中,MySQL会很乐意的去做你所要求的。

DELETE关键字之后应该包含别名:

 DELETE th FROM term_hierarchy AS th WHERE th.parent = 1015 AND th.tid IN ( SELECT DISTINCT(th1.tid) FROM term_hierarchy AS th1 INNER JOIN term_hierarchy AS th2 ON (th1.tid = th2.tid AND th2.parent != 1015) WHERE th1.parent = 1015 ); 

您需要在删除语句中再次引用别名,如:

 DELETE th FROM term_hierarchy AS th .... 

正如这里在MySQL文档中所概述的。

我以一种稍微不同的方式处理了这个问题,并为我工作。

我需要从我的表中删除secure_links引用conditions表,其中不再有任何条件行左。 一个家政脚本基本上。 这给了我错误 – 你不能指定目标表进行删除。

所以在这里寻找灵感,我想出了下面的查询,它工作得很好。 这是因为它创build了一个临时表sl1 ,用作DELETE的参考。

 DELETE FROM `secure_links` WHERE `secure_links`.`link_id` IN ( SELECT `sl1`.`link_id` FROM ( SELECT `sl2`.`link_id` FROM `secure_links` AS `sl2` LEFT JOIN `conditions` ON `conditions`.`job` = `sl2`.`job` WHERE `sl2`.`action` = 'something' AND `conditions`.`ref` IS NULL ) AS `sl1` ) 

为我工作。

是不是在删除中的“in”子句…其中,效率非常低,如果将要从子查询返回大量的值? 不知道为什么你不会只是内部(或右)从ID的子查询返回原来的表删除,而不是我们的“in(subquery)”。

 DELETE T FROM Target AS T RIGHT JOIN (full subquery already listed for the in() clause in answers above) ` AS TT ON (TT.ID = T.ID) 

也许这是在“MySQL不允许它”的答案,但是,它对我来说工作正常提供我确保完全澄清要删除的内容(从目标AS删除T)。 在MySQL中使用Join进行删除将阐明DELETE / JOIN问题。