如何从 MySQL 中的多个表中删除?

Posted

技术标签:

【中文标题】如何从 MySQL 中的多个表中删除?【英文标题】:How to delete from multiple tables in MySQL? 【发布时间】:2011-03-20 21:46:07 【问题描述】:

我试图一次从几个表中删除。我做了一些研究,并想出了这个

DELETE FROM `pets` p,
            `pets_activities` pa
      WHERE p.`order` > :order
        AND p.`pet_id` = :pet_id
        AND pa.`id` = p.`pet_id`

但是,我收到了这个错误

未捕获的 Database_Exception [1064]:您的 SQL 语法有错误;检查与您的 mysql 服务器版本相对应的手册,了解在 'p, pets_activities pa... 附近使用的正确语法。

我以前从来没有做过交叉表删除,所以我没有经验,暂时卡住了!

我做错了什么?

【问题讨论】:

【参考方案1】:

DELETE 语句中使用JOIN

DELETE p, pa
      FROM pets p
      JOIN pets_activities pa ON pa.id = p.pet_id
     WHERE p.order > :order
       AND p.pet_id = :pet_id

您也可以使用...

DELETE pa
      FROM pets_activities pa
      JOIN pets p ON pa.id = p.pet_id
 WHERE p.order > :order
   AND p.pet_id = :pet_id

...仅从pets_activities删除

见this。

对于单个表删除,但具有引用完整性,还有其他方法可以处理EXISTSNOT EXISTSINNOT IN 等。但上面的一种方法是您指定要从哪些表中删除在FROM 子句之前使用别名可以让您更轻松地摆脱一些非常紧张的问题。在 99% 的情况下,我倾向于联系EXISTS,然后有 1% 的情况需要这种 MySQL 语法。

【讨论】:

我尝试了这个“delete all in 1 query”,加入了 6 个大表(每个人大约 15k 行),查询用了 155 秒删除了 6 个表中的 63 行:O @cadman 这是真正的正确答案;可能有人反对使用它,但它有时非常有用 +1 我同意这在真正的正确答案中,因为问题不是“你应该”而是“如何”。但是,我很想听听 1% 的情况,因为我想不出哪种情况更适合这种情况。 @techouse,你加入并过滤索引了吗? 15k x 15k x 15k x 15k 15k x 15k 是 1100 万。 SELECT 是否需要同样长的时间? 你也可以使用 LEFT JOIN,如果第二个表没有匹配的条目,这很有用,否则什么都不会被删除。【参考方案2】:

由于这似乎是 petspets_activities 之间的简单父/子关系,因此您最好使用删除级联创建外键约束。

这样,当pets 行被删除时,与之关联的pets_activities 行也会被自动删除。

那么你的查询就变得简单了:

delete from `pets`
    where `order` > :order
      and `pet_id` = :pet_id

【讨论】:

@Erick,只要您设置了参照完整性,级联删除不会比单独删除更麻烦。由于id/pet_id 映射,我们已经知道pap 的正确子代。 好吧,你们有自己的想法,但似乎你们低估了 DBMS 的很多功能。级联删除与触发器、存储过程或约束一样是数据管理的一部分,并且只有在您不知道自己在做什么时才会产生危险。不过,我不会进一步争论这一点,我们只需要同意不同意。 埃里克,现在你已经引起了我的兴趣。如何在不受约束的情况下确保数据库内的数据完整性? @Erick 说,“我也不使用触发器、存储过程或约束。”啊,你使用Excel。 :-) 我只想跟进这件事。在这种情况下,我改变了删除级联的立场。我一直是使用它们的新 SQL 环境的一部分,并且很好地使用它们并且它们非常有条理。在这个系统中,将这些级联放置到位对我们来说非常有利。它当然可以防止孤立数据并且并不危险。问题是每个使用数据库的人都需要了解如何安全地使用它们。但是,当初级开发人员在无人监督的情况下更改数据库时,总是存在风险。【参考方案3】:

使用这个

DELETE FROM `articles`, `comments` 
USING `articles`,`comments` 
WHERE `comments`.`article_id` = `articles`.`id` AND `articles`.`id` = 4

DELETE `articles`, `comments` 
FROM `articles`, `comments` 
WHERE `comments`.`article_id` = `articles`.`id` AND `articles`.`id` = 4

【讨论】:

在mysqltutorial.org/mysql-delete-statement.aspx找到了使用此选项和其他一些选项的良好参考【参考方案4】:

我目前没有要测试的 mysql 数据库,但是您是否尝试过在 from 子句之前指定要删除的内容?例如:

DELETE p, pa FROM `pets` p,
        `pets_activities` pa
  WHERE p.`order` > :order
    AND p.`pet_id` = :pet_id
    AND pa.`id` = p.`pet_id`

我认为您使用的语法仅限于较新版本的 mysql。

【讨论】:

该查询成功执行,但是,它没有删除任何行(但我相信它应该删除)。【参考方案5】:

语法对我来说是正确的...尝试将其更改为使用INNER JOIN ...

看看this。

【讨论】:

很遗憾你没有包含实际的解决方案,因为链接是正确的!【参考方案6】:

对于 2017 年阅读本文的任何人,这就是我所做的类似事情的方式。

DELETE pets, pets_activities FROM pets inner join pets_activities
on pets_activities.id = pets.id WHERE pets.`order` > :order AND 
pets.`pet_id` = :pet_id

一般来说,要从多个表中删除行,我遵循的语法如下所示。该解决方案基于两个表之间存在某种关系的假设。

DELETE table1, table2 FROM table1 inner join table2 on table2.id = table1.id
WHERE [conditions]

【讨论】:

【参考方案7】:

我发现这篇文章向您展示了如何使用 MySQL DELETE JOIN 语句从多个表中删除数据,并有很好的解释。

【讨论】:

以上是关于如何从 MySQL 中的多个表中删除?的主要内容,如果未能解决你的问题,请参考以下文章

如何从mysql中的表中删除重复的行

MySql - 删除多个表中的相同字段

如何从mysql5中的父表中删除数据?

如何从Mysql中的所有表中删除一条唯一记录

如何在从多个表中获取多行的同时删除 sql JOIN 中的重复项

如何在 SQL Server 中使用 INNER JOIN 从多个表中删除