Löschen Sie SQL-Zeilen, bei denen IDs nicht mit einer anderen Tabelle übereinstimmen


159

Ich versuche, verwaiste Einträge in einer MySQL-Tabelle zu löschen.

Ich habe 2 Tabellen wie diese:

Tabelle files:

| id | ....
------------
| 1  | ....
| 2  | ....
| 7  | ....
| 9  | ....

Tabelle blob:

| fileid | ....
------------
| 1  | ....
| 2  | ....
| 3  | ....
| 4  | ....
| 4  | ....
| 4  | ....
| 9  | ....

Die Spalten fileidund idkönnen verwendet werden, um die Tabellen miteinander zu verbinden.

Ich möchte alle Zeilen in der Tabelle löschen , blobwo fileidnicht in der Tabelle zu finden files.id.

Verwenden Sie also das obige Beispiel, um die Zeilen zu löschen: 3 & 4 (s) in der blobTabelle.


1
Fahren Sie mit der zweiten Antwort fort, wenn Sie nulls verwenden.
— Pacerier

Antworten:


326

Verwenden von LEFT JOIN / IS NULL:

DELETE b FROM BLOB b 
  LEFT JOIN FILES f ON f.id = b.fileid 
      WHERE f.id IS NULL

Verwenden von NOT EXISTS:

DELETE FROM BLOB 
 WHERE NOT EXISTS(SELECT NULL
                    FROM FILES f
                   WHERE f.id = fileid)

Verwenden von NOT IN:

DELETE FROM BLOB
 WHERE fileid NOT IN (SELECT f.id 
                        FROM FILES f)

Warnung

Führen Sie nach Möglichkeit DELETEs innerhalb einer Transaktion aus (vorausgesetzt, unterstützt - IE: Nicht unter MyISAM), damit Sie bei Problemen mithilfe des Rollbacks Änderungen rückgängig machen können.


12
Welches ist im Allgemeinen das schnellste der oben genannten?
— Hampus Brynolf

2
Aus irgendeinem Grund funktionierte das Löschen mit LEFT JOIN unter MS SQL Server Mgmt Studio nicht (nicht sicher warum; es wurde nur über LEFT JOIN geklagt). Weiß jemand warum das so ist? Es hat mit NOT EXISTS funktioniert :)
— Anna


2
@ Pacerier - "falsch" ist ein bisschen stark. Um sicherzustellen , dass die Menschen verstehen, die Antworten zu tun Arbeit , wenn fileidist nicht nullable . Auch die dritte Lösung ( NOT IN) erfordert nur, dass f.idnicht nullbar. Vermutlich ist das ein Primärschlüssel, also wäre es.
— ToolmakerSteve

2
Für Leute, die dies mit SQLite versuchen: siehe diese Antwort
— Bunkerdive

26
DELETE FROM blob 
WHERE fileid NOT IN 
       (SELECT id 
        FROM files 
        WHERE id is NOT NULL/*This line is unlikely to be needed 
                               but using NOT IN...*/
      )

Was ist "/ * Diese Zeile wird wahrscheinlich nicht benötigt, aber die Verwendung von NOT IN ... * /" soll bedeuten?
— Pacerier

1
@Pacerier - Gibt NOT IN (NULL)eine leere Ergebnismenge zurück, sodass NULL-Werte ausgeschlossen werden müssen. Aber eine idSpalte wird wahrscheinlich sowieso nicht nullbar sein, daher "wahrscheinlich nicht benötigt"
— Martin Smith

Wow guter Fang. Die Antwort von Omgponys ist also falsch! not in(null)ist ziemlich logisch, warum funktioniert es nicht? Was ist der Grund dafür?
— Pacerier


1
@bunkerdive Verwenden Sie dann dreiteilige Objektnamen, die den Datenbanknamen enthalten.
— Martin Smith

17
DELETE FROM blob
WHERE NOT EXISTS (
    SELECT *
    FROM files
    WHERE id=blob.id
)

1
Ich denke es gibt ein files.idund blob.fileid. Ich vermute, Ihre Anfrage wird zu einem Fehler führen.
— JWW

-8
delete from table1 t1 
    WHERE not exists (select id from table2 where related_field_in_t2=t1.id) 
    AND not exists (select id from table3 where related_field_in_t3=t1.id) 
    AND not exists (select id from table4 where related_field_t4=t1.id) 
    AND not exists (select id from table5 where related_field_t5=t1.id);

3
Ich habe abgestimmt, weil: 1. Dies versucht nicht, die Frage in dem Kontext zu beantworten, der veröffentlicht wurde. 2. Es gibt keine Erklärung (und Nur-Code-Antworten sind bei Stackoverflow von geringem Wert). 3. NOT EXISTSwurde bereits vor 9 Jahren veröffentlicht. 4. Sie haben nicht für die bewährte Methode geworben, All-Caps für MySQL-Schlüsselwörter konsequent zu verwenden. Mit anderen Worten, hier gibt es nichts, was es wert wäre, behalten zu werden - deshalb habe ich auch dafür gestimmt, diesen Beitrag zu löschen.
— Mickmackusa
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.