How to delete from multiple tables in MySQL?

222,050

Solution 1

Use a JOIN in the DELETE statement.

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

Alternatively you can use...

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

...to delete only from pets_activities

See this.

For single table deletes, yet with referential integrity, there are other ways of doing with EXISTS, NOT EXISTS, IN, NOT IN and etc. But the one above where you specify from which tables to delete with an alias before the FROM clause can get you out of a few pretty tight spots more easily. I tend to reach out to an EXISTS in 99% of the cases and then there is the 1% where this MySQL syntax takes the day.

Solution 2

Since this appears to be a simple parent/child relationship between pets and pets_activities, you would be better off creating your foreign key constraint with a deleting cascade.

That way, when a pets row is deleted, the pets_activities rows associated with it are automatically deleted as well.

Then your query becomes a simple:

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

Solution 3

Use this

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

or

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

Solution 4

I don't have a mysql database to test on at the moment, but have you tried specifying what to delete prior to the from clause? For example:

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`

I think the syntax you used is limited to newer versions of mysql.

Solution 5

The syntax looks right to me ... try to change it to use INNER JOIN ...

Have a look at this.

Share:
222,050
user3167101
Author by

user3167101

I like to make stuff. Check out my blog. You can email me at alex at my domain. My dotfiles, if you're curious :)

Updated on March 10, 2020

Comments

  • user3167101
    user3167101 about 4 years

    I am trying to delete from a few tables at once. I've done a bit of research, and came up with this

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

    However, I am getting this error

    Uncaught Database_Exception [ 1064 ]: 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 'p, pets_activities pa...

    I've never done a cross table delete before, so I'm inexperienced and stuck for now!

    What am I doing wrong?

  • Erick Robertson
    Erick Robertson almost 14 years
    Delete cascades are inviting horrible accidents.
  • user3167101
    user3167101 almost 14 years
    Thanks Paxdiablo, I'm not sure how to do this yet in MySQL but I'll consider it.
  • paxdiablo
    paxdiablo almost 14 years
    @Erick, provided you've set up referential integrity, cascading deletes can cause no more trouble than delete on its own. We already know that pa is a proper child of p due to the id/pet_id mapping.
  • Erick Robertson
    Erick Robertson almost 14 years
    Cascading deletes just means that things will be deleted which you aren't explicitly saying to delete. That's always dangerous.
  • paxdiablo
    paxdiablo almost 14 years
    You are explicitly saying you want to delete them. Just not at the time of delete. You don't explicitly say you want triggers fired at the time of insertion either but that doesn't make them dangerous.
  • Erick Robertson
    Erick Robertson almost 14 years
    I disagree. I prefer to use a database as a database, and not as an execution platform.
  • OMG Ponies
    OMG Ponies almost 14 years
    I agree with Erick on this one - can be hazardous. Somewhat related, SQL Server 2005 doesn't handle cascade deletes if on the same table. The safest means is to process data in relational order
  • paxdiablo
    paxdiablo almost 14 years
    Well, you guys have your own thoughts but it seems like you're discounting a lot of the power of DBMS'. Cascading deletes are as much a part of data management as triggers, stored procedures or constraints and they're only dangerous if you don't know what you're doing. Still, I won't argue the point further, we'll just have to agree to disagree.
  • OMG Ponies
    OMG Ponies almost 14 years
    Getting data in isn't the issue - it's situations where you have to reconstruct data that wasn't supposed to be deleted which is a real hassle. Only Oracle has Flashback, a temporal compliment to it's database for inline reconstituting accidentally deleted data. SQL Server has snapshots, but it's nowhere near as slick as Flashback. That's why Erick, myself, and numerous others I've worked with prefer explicit deletion. Like the case with SQL Server, it's not always a cut'n'dried operation either, or hasn't been in the past.
  • user3167101
    user3167101 almost 14 years
    That query executed successfully, however, it didn't delete any rows (but I believe it should have).
  • paxdiablo
    paxdiablo almost 14 years
    Again, not an issue if it's set up correctly - the problems you mention are no different to deleting rows accidentally without cascade. Seriously, if someone doesn't know how to design and implement databases, they have no business trying to do it.
  • Erick Robertson
    Erick Robertson almost 14 years
    It probably comes as no surprise, but I also do not use triggers, stored procedures, or constraints. I prefer to put this kind of logic in my execution platform and use my database for storing and retrieving data only. This doesn't mean I don't know how to use or understand these features, however.
  • paxdiablo
    paxdiablo almost 14 years
    Erick, now you've piqued my interest. How do you ensure data integrity within the database without constraints?
  • Klemen Tusar
    Klemen Tusar almost 12 years
    I tried this "delete all in 1 query" with joining 6 large tables (everyone about ~15k rows) and the query took 155 seconds to delete 63 rows in 6 tables :O
  • Simon Christian
    Simon Christian about 11 years
    @cadman This is the real right answer; there may be arguments against using it, but it's very useful on occasion
  • james.garriss
    james.garriss over 10 years
    @Erick said, "I also do not use triggers, stored procedures, or constraints." Ah, you use Excel. :-)
  • Erick Robertson
    Erick Robertson over 10 years
    I just want to follow up on this. I have changed my position on deleting cascades in this situation. I have been a part of a new SQL environment which used them, and used them well and they were very organized. In this system it worked very well to our advantage to have these cascades in place. It certainly prevented orphaned data and was not dangerous. The problem is that everyone working with the database needs to understand how to use them safely. But there are always risks when junior devs are making database changes unsupervised.
  • Erick Robertson
    Erick Robertson over 10 years
    +1 I agree that this in the real right answer, since the question was not "should you" but "how to". However, I would be interested in hearing about the 1% because I can't think of a single situation where this would be preferred.
  • mycroes
    mycroes almost 10 years
    Too bad you didn't include the actual solution, because the link is correct!
  • Paul Draper
    Paul Draper almost 10 years
    @techouse, did you join and filter on indices? 15k x 15k x 15k x 15k 15k x 15k is 11 million. Did a SELECT take similarly long?
  • Lexib0y
    Lexib0y over 8 years
    You can also use LEFT JOIN, which is usefull if the second table had no matching entries, else nothing will be deleted.
  • zhuguowei
    zhuguowei almost 8 years
    Thanks, but I met another question when execute delete in safe-update mode, please see stackoverflow.com/questions/37892657/…
  • Mavelo
    Mavelo over 7 years
    Found a good reference for using this and a few other options at mysqltutorial.org/mysql-delete-statement.aspx