如何从 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。
对于单个表删除,但具有引用完整性,还有其他方法可以处理EXISTS
、NOT EXISTS
、IN
、NOT 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】:
由于这似乎是 pets
和 pets_activities
之间的简单父/子关系,因此您最好使用删除级联创建外键约束。
这样,当pets
行被删除时,与之关联的pets_activities
行也会被自动删除。
那么你的查询就变得简单了:
delete from `pets`
where `order` > :order
and `pet_id` = :pet_id
【讨论】:
@Erick,只要您设置了参照完整性,级联删除不会比单独删除更麻烦。由于id/pet_id
映射,我们已经知道pa
是p
的正确子代。
好吧,你们有自己的想法,但似乎你们低估了 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 中的多个表中删除?的主要内容,如果未能解决你的问题,请参考以下文章