【问题标题】:How to delete from multiple tables in MySQL?如何从 MySQL 中的多个表中删除?
【发布时间】:2021-04-07 05:38:40
【问题描述】:

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

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... 附近使用的正确语法。

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

我做错了什么?

【问题讨论】:

    标签: mysql sql mysql-error-1064 sql-delete


    【解决方案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
    

    【讨论】:

    【解决方案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 语句从多个表中删除数据,并有很好的解释。

      【讨论】:

        猜你喜欢
        • 2014-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多