2010-07-26 8 views
85

Ich versuche, aus ein paar Tabellen auf einmal zu löschen. Ich habe ein bisschen recherchiert und kam mit diesemWie lösche ich aus mehreren Tabellen in MySQL?

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

Allerdings erhalte ich diesen Fehler

Uncaught Database_Exception [1064]: Sie haben einen Fehler in der SQL-Syntax; Sie in der Bedienungsanleitung zu Ihrem MySQL-Server-Version für den richtigen Syntax entspricht verwenden in der Nähe von ‚p, pets_activities pa ...

Ich habe noch nie löschen ein Kreuztisch getan, so dass ich bin unerfahren und steckte für jetzt!

Was mache ich falsch?

Antwort

153

Verwenden Sie eine JOIN in der DELETE Anweisung.

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 

Alternativ können Sie

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 

... nutzen ... nur

von pets_activities löschen http://dev.mysql.com/doc/refman/5.0/en/delete.html

Siehe Für einzelne Tabelle löscht, noch mit referentielle Integrität, Es gibt andere Möglichkeiten, mit EXISTS zu arbeiten, NOT EXISTS, IN, NOT IN usw. Aber die obige, wo Sie angeben, aus welchen Tabellen mit einem gelöscht werden soll Alias ​​vor der FROM-Klausel kann Sie aus ein paar ziemlich engen Stellen leichter zu bekommen. Ich neige dazu, in 99% der Fälle EXISTS zu erreichen, und dann gibt es 1%, wo diese MySQL-Syntax den Tag nimmt.

+5

Ich versuchte diese "lösche alle in 1 Abfrage" mit 6 große Tabellen (jeder über ~ 15k Zeilen) und die Abfrage dauerte 155 Sekunden, um 63 Zeilen in 6 Tabellen zu löschen: O – techouse

+1

@cadman Dies ist die richtige Antwort; Es kann Argumente gegen die Verwendung geben, aber es ist sehr nützlich bei Gelegenheit –

+1

+1 Ich stimme zu, dass dies in der richtigen Antwort, denn die Frage war nicht "sollten Sie", sondern "wie". Ich wäre jedoch interessiert, von der 1% zu hören, weil ich mir keine einzige Situation vorstellen kann, in der dies vorzuziehen wäre. –

17

Da dies scheint eine einfache Eltern/Kind-Beziehung zu sein zwischen pets und pets_activities, wäre es besser, wenn Sie Ihre Fremdschlüsseleinschränkung mit einer Löschkaskade erstellen.

Wenn eine pets Zeile gelöscht wird, werden die damit verknüpften pets_activities Zeilen automatisch gelöscht.

dann Ihre Abfrage wird zu einem einfachen:

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

Löschen Kaskaden laden schreckliche Unfälle ein. –

+0

Danke Paxdiablo, ich bin mir nicht sicher, wie ich das in MySQL machen soll, aber ich werde darüber nachdenken. – alex

+2

@Erick, vorausgesetzt, Sie haben die referenzielle Integrität eingerichtet, können kaskadierende Löschvorgänge keine Probleme mehr verursachen, als selbst zu löschen. Wir wissen bereits, dass 'pa' aufgrund der' id/pet_id'-Zuordnung ein korrektes Kind von 'p' ist. – paxdiablo

2

ich im Moment nicht über eine MySQL-Datenbank testen auf, aber haben Sie versucht, die festlegen, was die von Klausel vor löschen? Zum Beispiel:

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` 

Ich denke, dass die Syntax, die Sie verwendeten, auf neuere Versionen von mysql beschränkt ist.

+1

Diese Abfrage wurde erfolgreich ausgeführt, löschte jedoch keine Zeilen (aber ich glaube, sie sollte haben). – alex

12

verwenden

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

oder

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

Schön - scheint besser und einfacher als mit JOIN. Es ist die beste Lösung, die ich hier sehe. Danke! – gnB

+1

Eine gute Referenz für die Verwendung dieser und einiger anderer Optionen gefunden unter http://www.mysqltutorial.org/mysql-delete-statement.aspx –

0

Um jemand dies im Jahr 2017 zu lesen, das ist, wie ich etwas Ähnliches getan haben.

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 

Im Allgemeinen, um Zeilen aus mehreren Tabellen zu löschen, ist die Syntax, die ich folge, unten angegeben. Die Lösung basiert auf der Annahme, dass zwischen den beiden Tabellen eine Beziehung besteht.

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