580 Stimmen

Löschen mit Join in MySQL

Hier ist das Skript zum Erstellen meiner Tabellen:

CREATE TABLE clients (
   client_i INT(11),
   PRIMARY KEY (client_id)
);
CREATE TABLE projects (
   project_id INT(11) UNSIGNED,
   client_id INT(11) UNSIGNED,
   PRIMARY KEY (project_id)
);
CREATE TABLE posts (
   post_id INT(11) UNSIGNED,
   project_id INT(11) UNSIGNED,
   PRIMARY KEY (post_id)
);

Wenn ich in meinem PHP-Code einen Kunden lösche, möchte ich alle Projektbeiträge löschen:

DELETE 
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id;

Die Tabelle posts hat keinen Fremdschlüssel client_id nur project_id . Ich möchte die Stellen in den Projekten löschen, die den Pass client_id .

Dies funktioniert im Moment nicht, da keine Beiträge gelöscht werden.

13 Stimmen

Ich denke, Yehosef Antwort sollte die akzeptierte sein, da er Join verwendet, wie Sie gefragt und dass es besser als mit einer IN-Klausel, wie yukondude vorgeschlagen...

3 Stimmen

Das bevorzugte Muster ist ein DELETE posts FROM posts JOIN projects ... und nicht eine IN (subquery) Muster. (Die Antwort von Yehosef gibt ein Beispiel für das bevorzugte Muster).

1 Stimmen

@GerardoGrignoli, führt es besser für eine bestimmte Engine oder Version von MySQL? Es gibt keinen Grund, warum die beiden Abfragen unterschiedlich funktionieren sollten, da sie AFAIK identisch sind. Natürlich, wenn ich einen Nickel für jedes Mal hätte, wenn mein Abfrageoptimierer etwas Dummes macht....

17voto

1000111 Punkte 12669

Einzelne Tabelle löschen:

Um Einträge zu löschen aus posts Tisch:

DELETE ps 
FROM clients C 
INNER JOIN projects pj ON C.client_id = pj.client_id
INNER JOIN posts ps ON pj.project_id = ps.project_id
WHERE C.client_id = :client_id;

Um Einträge zu löschen aus projects Tisch:

DELETE pj 
FROM clients C 
INNER JOIN projects pj ON C.client_id = pj.client_id
INNER JOIN posts ps ON pj.project_id = ps.project_id
WHERE C.client_id = :client_id;

Um Einträge zu löschen aus clients Tisch:

DELETE C
FROM clients C 
INNER JOIN projects pj ON C.client_id = pj.client_id
INNER JOIN posts ps ON pj.project_id = ps.project_id
WHERE C.client_id = :client_id;

Mehrere Tabellen löschen:

Um Einträge aus mehreren Tabellen aus den verbundenen Ergebnissen zu löschen, müssen Sie die Tabellennamen nach DELETE als kommagetrennte Liste:

Angenommen, Sie wollen Einträge aus allen drei Tabellen löschen ( posts , projects , clients ) für einen bestimmten Kunden:

DELETE C,pj,ps 
FROM clients C 
INNER JOIN projects pj ON C.client_id = pj.client_id
INNER JOIN posts ps ON pj.project_id = ps.project_id
WHERE C.client_id = :client_id

12voto

Aman Garg Punkte 2791

MySQL DELETE-Datensätze mit JOIN

Im Allgemeinen verwenden Sie INNER JOIN in der SELECT-Anweisung, um Datensätze aus einer Tabelle auszuwählen, die entsprechende Datensätze in anderen Tabellen haben. Die INNER JOIN-Klausel kann auch mit der DELETE-Anweisung verwendet werden, um Datensätze aus einer Tabelle und die entsprechenden Datensätze in anderen Tabellen zu löschen. Um z. B. Datensätze aus den beiden Tabellen T1 und T2 zu löschen, die eine bestimmte Bedingung erfüllen, verwenden Sie die folgende Anweisung:

DELETE T1, T2
FROM T1
INNER JOIN T2 ON T1.key = T2.key
WHERE condition

Beachten Sie, dass Sie die Tabellennamen T1 und T2 zwischen DELETE und FROM setzen. Wenn Sie die Tabelle T1 weglassen, löscht die DELETE-Anweisung nur Datensätze in der Tabelle T2, und wenn Sie die Tabelle T2 weglassen, werden nur Datensätze in der Tabelle T1 gelöscht.

Die Join-Bedingung T1.Schlüssel = T2.Schlüssel gibt die entsprechenden Sätze in der Tabelle T2 an, die gelöscht werden müssen.

Die Bedingung in der WHERE-Klausel gibt an, welche Datensätze in T1 und T2 gelöscht werden müssen.

7voto

Versuchen Sie es wie unten:

DELETE posts.*,projects.* 
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id;

4voto

Jim Clouse Punkte 8234

Eine andere Methode des Löschens mit einer Unterauswahl, die besser ist als die Verwendung von IN wäre WHERE EXISTS

DELETE  FROM posts
WHERE   EXISTS ( SELECT  1 
                 FROM    projects
                 WHERE   projects.client_id = posts.client_id);

Ein Grund, dies anstelle der Verknüpfung zu verwenden, ist, dass eine DELETE con JOIN verbietet die Verwendung von LIMIT . Wenn Sie in Blöcken löschen möchten, um keine vollständigen Tabellensperren zu erzeugen, können Sie Folgendes hinzufügen LIMIT dies verwenden DELETE WHERE EXISTS Methode.

1 Stimmen

Kann diese Abfrage mit "Aliasen" geschrieben werden? Aus der Syntax geht nicht ganz klar hervor, wie die posts innerhalb von EXISTS() ist dasselbe posts aus dem die Zeilen gelöscht werden. (IMHO jedenfalls)

0 Stimmen

Ich verstehe Sie, aber Aliase sind in der Tabelle zum Löschen nicht erlaubt. Das "posts" in der Unterabfrage muss der vollständige Tabellenname sein, d. h., wenn Sie diese Tabelle in Ihrer Unterauswahlklausel "From" wiederverwenden wollten, müssten Sie sie dort mit einem Alias versehen.

1 Stimmen

Das funktioniert: DELETE p FROM posts p WHERE EXISTS ( SELECT 1 FROM projects WHERE projects.client_id = p.client_id);

4voto

zloctb Punkte 9390
mysql> INSERT INTO tb1 VALUES(1,1),(2,2),(3,3),(6,60),(7,70),(8,80);

mysql> INSERT INTO tb2 VALUES(1,1),(2,2),(3,3),(4,40),(5,50),(9,90);

DELETE-Datensätze aus einer Tabelle :

mysql> DELETE tb1 FROM tb1,tb2 WHERE tb1.id= tb2.id;

DELETE RECORDS FROM beide Tabellen:

mysql> DELETE tb2,tb1 FROM tb2 JOIN tb1 USING(id);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X