Löschen Sie aus zwei Tabellen in einer Abfrage

82

Ich habe zwei Tabellen in MySQL

#messages table  : 
messageid
messagetitle 
.
.

#usersmessages table 
usersmessageid 
messageid
userid
.
.

Wenn ich jetzt aus der Nachrichtentabelle löschen möchte, ist das in Ordnung. Wenn ich jedoch eine Nachricht mit der Nachrichten-ID lösche, ist der Datensatz in der Benutzernachricht weiterhin vorhanden, und ich muss diese beiden Tabellen gleichzeitig löschen.

Ich habe die folgende Abfrage verwendet:

DELETE FROM messages LEFT JOIN usersmessages USING(messageid) WHERE messageid='1' ; 

Dann teste ich

   DELETE FROM messages , usersmessages 
   WHERE messages.messageid = usersmessages.messageid 
   and messageid='1' ; 

Diese beiden Abfragen erfüllen diese Aufgabe jedoch nicht.

mehdi
quelle

Antworten:

135

Können Sie sie nicht einfach durch ein Semikolon trennen?

Delete from messages where messageid = '1';
Delete from usersmessages where messageid = '1'

ODER

Verwenden Sie einfach INNER JOINwie unten

DELETE messages , usersmessages  FROM messages  INNER JOIN usersmessages  
WHERE messages.messageid= usersmessages.messageid and messages.messageid = '1'
Eric
quelle
1
Was passiert, wenn ich diesen Code in eine Schleife setzen möchte? Ich weiß, ich kann das Semikolon absolut setzen.
Mehdi
1
Es kann in eine Schleife gestellt werden. Sie können dies programmgesteuert tun und die Nachrichten-ID als Parameter senden. Solange Sie nicht immer dieselbe ID senden, wird das Löschen nicht immer wieder durchgeführt.
Eric
4
Wenn Sie dies in zwei Abfragen tun, sollten Sie dies wirklich in eine Transaktion einschließen. Wenn Sie Löschabfragen in einer Schleife ausführen möchten, sollten Sie eine einzige Abfrage formulieren, um alle Löschvorgänge durchzuführen.
JohnFx
1
Kasse ein weiteres Beispiel für eine Löschabfrage
Babar
18
Funktioniert nicht mit SQL Server: Falsche Syntax in der Nähe von ','.
Paul-Sebastian Manole
44
DELETE a.*, b.* 
FROM messages a 
LEFT JOIN usersmessages b 
ON b.messageid = a.messageid 
WHERE a.messageid = 1

Übersetzung: Löschen aus der Tabelle Nachrichten wo messageid = 1, wenn Tabelle uersmessages messageid = messageid der Tabelle hat Meldungen , dass die Reihe von löscht uersmessages Tabelle.

wütende Kiwi
quelle
Kommentar für alle: Wie in diesem Beispiel gezeigt, ist es wichtig anzugeben, in welcher Tabelle das Löschen funktionieren soll. Großartiger Beitrag @angry_kiwi
Raphael_b
Ich musste nur die Reihenfolge ändern, VON Benutzernachrichten b LEFT JOIN-Nachrichten a
Pablo
15

Sie sollten entweder ein FOREIGN KEYmit erstellen ON DELETE CASCADE:

ALTER TABLE usersmessages
ADD CONSTRAINT fk_usermessages_messageid
FOREIGN KEY (messageid)
REFERENCES messages (messageid)
ON DELETE CASCADE

oder verwenden Sie zwei Abfragen in einer Transaktion:

START TRANSACTION;;

DELETE
FROM    usermessages
WHERE   messageid = 1

DELETE
FROM    messages
WHERE   messageid = 1;

COMMIT;

Die Transaktion betrifft jedoch nur InnoDBTabellen.

Quassnoi
quelle
3
Sie können in einer Abfrage aus mehreren Tabellen löschen! dev.mysql.com/doc/refman/5.0/en/delete.html
txwikinger
Ja, du kannst! Aber für mich ... ist es einfacher zu tun, was meine Antwort sagte.
Eric
Ich fügte die Kaskade auf einem ähnlichen Tisch von mir hinzu. Als ich versuchte, nur aus einer Tabelle zu löschen, wurde der Datensatz gelöscht und die zugehörige verwaist. Was nützt die Einschränkung?
Barfoon
@ Barfoon: Ist dein Tisch InnoDB?
Quassnoi
@ Quassnoi Ups! Ich dachte definitiv, es wäre was für ein Trottel. Alle Tabellen sind MyISAM. Kann ich alle im laufenden Betrieb mit darin enthaltenen Daten ändern? Oder gibt es Probleme damit?
Barfoon
7

Sie haben zwei Möglichkeiten:

Führen Sie zunächst zwei Anweisungen innerhalb einer Transaktion aus:

BEGIN;
  DELETE FROM messages WHERE messageid = 1;
  DELETE FROM usermessages WHERE messageid = 1;
COMMIT;

Oder Sie können ON DELETE CASCADE mit einem Fremdschlüssel einrichten. Dies ist der bessere Ansatz.

CREATE TABLE parent (
  id INT NOT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE child (
  id INT, parent_id INT,
  FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
);

Weitere Informationen zu ON DELETE CASCADE finden Sie hier .

Mike Trpcic
quelle
7

keine Notwendigkeit für JOINS:

DELETE m, um FROM messages m, usersmessages um

WHERE m.messageid = 1 

AND m.messageid = um.messageid 
Fred Yates
quelle
6
DELETE message.*, usersmessage.* from users, usersmessage WHERE message.messageid=usersmessage.messageid AND message.messageid='1'
Johan
quelle
6

Dem OP fehlen nur die Tabellen-Aliase nach dem Löschen

DELETE t1, t2 
FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.id 
WHERE t1.id = some_id
Mark Angelo Pascual
quelle
3
Danke für deine Antwort. Es wäre hilfreicher, wenn Sie versuchen zu erklären, warum dies funktionieren würde und warum die OP-Lösung dies nicht tat.
DdW
1

Versuchen Sie dies bitte

DELETE FROM messages,usersmessages

USING messages

INNER JOIN usermessages on (messages.messageid = usersmessages.messageid)

WHERE messages.messsageid='1'
Amit
quelle
0

Versuche dies..

DELETE a.*, b.*  
FROM table1 as a, table2 as b  
WHERE a.id=[Your value here] and b.id=[Your value here]

Ich lasse idals Beispielsäule.

Ich bin froh, dass das hilft. :) :)

John Oliver Amurao
quelle
Damit asterikses ( *) richtig gerendert wird, müssen Sie die Abfrage mit 4 Leerzeichen davor einrücken .
Al.G.
0

Sie können dies auch verwenden, um einen bestimmten Wert zu löschen, wenn beide Spalten 2 oder viele des gleichen Spaltennamens haben.

DELETE project , create_test  FROM project INNER JOIN create_test
WHERE project.project_name='Trail' and  create_test.project_name ='Trail' and project.uid= create_test.uid = '1';
Vidya
quelle
0

Es gibt einen anderen Weg, der hier nicht erwähnt wird (ich habe die Leistung noch nicht vollständig getestet). Sie können das Array für alle Tabellen festlegen -> Zeilen, die Sie wie folgt löschen möchten

// set your tables array
$array = ['table1', 'table2', 'table3'];


// loop through each table
for($i = 0; $i < count($array); $i++){

 // get each single array
 $single_array = $array[$i];

 // build your query
 $query = "DELETE FROM $single_array WHERE id = 'id'";

 // prepare the query and get the connection
 $data = con::GetCon()->prepare($query);

 // execute the action
 $data->execute();
}

Dann können Sie den Benutzer auf die Startseite umleiten.

header('LOCATION:' . $home_page);

hoffe das hilft jemandem :)

Vielen Dank

Midz Elwekil
quelle
Dies könnte jemandem helfen ... sieht aber wie PHP aus, ich denke nicht, dass dies unbedingt im Rahmen der Frage liegt :)
Tom Bush