How to delete from multiple tables in MySQL?
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.
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, 2020Comments
-
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 almost 14 yearsDelete cascades are inviting horrible accidents.
-
user3167101 almost 14 yearsThanks Paxdiablo, I'm not sure how to do this yet in MySQL but I'll consider it.
-
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 ofp
due to theid/pet_id
mapping. -
Erick Robertson almost 14 yearsCascading deletes just means that things will be deleted which you aren't explicitly saying to delete. That's always dangerous.
-
paxdiablo almost 14 yearsYou 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 almost 14 yearsI disagree. I prefer to use a database as a database, and not as an execution platform.
-
OMG Ponies almost 14 yearsI 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 almost 14 yearsWell, 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 almost 14 yearsGetting 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 almost 14 yearsThat query executed successfully, however, it didn't delete any rows (but I believe it should have).
-
paxdiablo almost 14 yearsAgain, 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 almost 14 yearsIt 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 almost 14 yearsErick, now you've piqued my interest. How do you ensure data integrity within the database without constraints?
-
Klemen Tusar almost 12 yearsI 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 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 over 10 years@Erick said, "I also do not use triggers, stored procedures, or constraints." Ah, you use Excel. :-)
-
Erick Robertson over 10 yearsI 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 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 almost 10 yearsToo bad you didn't include the actual solution, because the link is correct!
-
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 over 8 yearsYou can also use LEFT JOIN, which is usefull if the second table had no matching entries, else nothing will be deleted.
-
zhuguowei almost 8 yearsThanks, but I met another question when execute
delete
insafe-update
mode, please see stackoverflow.com/questions/37892657/… -
Mavelo over 7 yearsFound a good reference for using this and a few other options at mysqltutorial.org/mysql-delete-statement.aspx