4

我有一个名为 items 的表,其列“itemID”和“parentID”,其中 parentID 是表中另一行的 ID。我想删除 parentID-row 不再存在的行。

这就是我想出的:

DELETE FROM items
WHERE (SELECT COUNT(1)
       FROM items as parent
       WHERE items.parentID=parent.itemID)=0

但我收到以下错误:您无法在 FROM 子句中指定目标表“项目”进行更新

编辑:如果链接到此查询删除的项目的项目也将被查询删除,那会很好,这可能在 sql 中还是我应该编码?

4

3 回答 3

7

使用子查询效率低下;使用多表语法的左连接:

DELETE items 
FROM items
    left join items as parent 
        on items.parentID = parent.itemID
WHERE parent.itemID is NULL

多表语法允许您在删除命令中指定连接 - 因此您可以连接多个表并且只从一个表中删除。即将 DELETE t1 FROM t1 join t2 ....加入t1t2仅从 table 中删除相应的行t1

至于您的问题“如果链接到此查询删除的项目的项目也将被查询删除,这在 sql 中是否可行,或者我应该对其进行编码?”

我认为这最终会导致级联 - 已删除的记录可能是另一条记录的父记录,因此也删除该记录,但该记录也可能是另一条记录的父记录,因此您也需要删除它,等等。我认为不可能通过单个 SQL 查询来查询所有这些级联。

所以我认为最简单的解决方案是重新运行上述查询,直到没有行被删除。

于 2013-06-13T09:43:55.747 回答
3

查询将是

DELETE items FROM items 
left join parent 
    on items.parentID = parent.ID
WHERE parent.ID is NULL
于 2013-06-13T09:46:21.403 回答
0

试试这个小魔法……

delete from FooTable f1 where f1.parent_id 
         not in (select f2.item_id from FooTable f2);

当然这个查询有一个小问题,如果你很敏锐,你可能会注意到,它可能会在没有父级的情况下生成新的 FooRecords(也就是说,它们的父级可能在查询执行期间被删除)。

如果您不需要自动执行查询,请手动执行多次查询,或者将其放在循环中并在已删除记录数为 0 时停止循环。

于 2013-06-13T10:38:13.030 回答