DELETE: Zeilen löschen
Kurz gesagt: DELETE FROM … WHERE löscht Zeilen, die die Bedingung erfüllen; ohne WHERE verschwinden alle, und ein Fremdschlüssel verbietet das Löschen einer Zeile, auf die andere zeigen.
Problem
Nimm meine Bewertung runter
Im Januar hat Maria eine Bewertung für das Waschpulver geschrieben: „Das Paket kam zerrissen an.“ Der Shop hat ihr ein neues Paket geschickt. Jetzt schreibt Maria an den Support und bittet darum, die Bewertung zu entfernen.
Die Zeile muss aus reviews verschwinden. Nur diese eine, nicht Marias andere Bewertungen.
Die Idee
DELETE FROM … WHERE
DELETE FROM sagt, aus welcher Tabelle, und WHERE sagt, welche Zeilen:
Bewertung 7 ist weg, und Marias andere Bewertung, die für das Weißbrot, ist noch da. DELETE entfernt ganze Zeilen. Spalten werden nicht aufgeführt.
Die Zeile ist nur in dieser Datenbank gelöscht. „Neue Datenbank“ bringt sie zurück.
Probier es aus
Ein geschlossenes Konto
Teodora Genova (Kunde 19) hat sich im September angemeldet, aber noch nichts bestellt. Heute schließt sie ihr Konto. Lösche sie.
Lösung
DELETE FROM customers WHERE id = 19;DELETE FROM customers WHERE id = 19. Es bleiben 19 Kunden. Teodora hat keine Bestellungen und keine Bewertungen, deshalb erlaubt die Datenbank es. Auf der nächsten Karte ist es anders.
Sieh es dir an
Ein Kunde mit Bestellungen
Auch Maria will ihr Konto schließen. Probier es aus:
Die Datenbank weigert sich. Maria hat 12 Bestellungen und zwei Bewertungen, und sie zeigen mit einem Fremdschlüssel (customer_id) auf sie. Wäre ihre Zeile weg, gehörten die Bestellungen niemandem.
Das ist eine Regel der Tabelle, wie UNIQUE und CHECK aus der ersten Lektion. Im nächsten Modul schreibst du sie selbst und wählst, was mit den Bestellungen passiert, wenn der Kunde gelöscht wird.
Sieh es dir an
DELETE ohne WHERE
Vergiss WHERE, und jede Zeile verschwindet:
16 Bewertungen, über ein ganzes Jahr gesammelt, verschwinden mit einer Anweisung. Die Tabelle bleibt, aber sie ist leer. Klick auf „Neue Datenbank“, um sie zurückzuholen.
Bei den Kunden geht das nicht so:
Die meisten Kunden haben Bestellungen, deshalb wird die ganze Anweisung abgebrochen. Nicht einmal die Kunden ohne Bestellungen werden gelöscht: Entweder läuft die ganze Anweisung, oder gar nichts. Die Gewohnheit aus der vorigen Lektion gilt also auch hier: erst ein SELECT mit demselben WHERE.
Die Idee
Soft Delete
Georgi Petrov storniert seine neue Bestellung 57. Löschen funktioniert nicht, weil Produkte in der Bestellung sind:
Du könntest erst ihre Zeilen aus order_items löschen und dann die Bestellung selbst. Aber Shops machen das selten. Stattdessen wird die Bestellung storniert:
Das ist ein Soft Delete: Die Zeile bleibt, ist aber als gelöscht oder storniert markiert. Warum Shops das bevorzugen:
- Die Auswertungen bleiben richtig. Wie viele Bestellungen storniert werden und warum, ist eine wichtige Frage.
- Die Buchhaltung braucht jede Bestellung, zu der es eine Zahlung gab.
- Der Support sieht den Verlauf, wenn der Kunde anruft.
- Ein Fehler lässt sich beheben. Was storniert ist, kommt mit einem
UPDATEzurück. Was gelöscht ist, kommt nicht zurück.
Der Preis: Jede Abfrage muss die stornierten im Kopf haben. Die Verkaufsauswertung braucht WHERE status <> 'cancelled'.
Genauer, für Neugierige
In vielen Systemen hat jede Tabelle eine Spalte deleted_at: NULL für die lebenden Zeilen, ein Datum für die „gelöschten“. Dann hat jede Abfrage WHERE deleted_at IS NULL. Wie du einer Tabelle eine Spalte hinzufügst, siehst du im nächsten Modul.
Manchmal ist Löschen Pflicht. Wenn eine Person verlangt, dass ihre Daten entfernt werden (das „Recht auf Vergessenwerden“ in der DSGVO), müssen die personenbezogenen Daten weg. Oft werden Name und E-Mail-Adresse gelöscht oder ersetzt, und die Bestellungen bleiben ohne sie für die Buchhaltung bestehen.
Probier es aus
Keine Gurken
Die Gurken (Produkt 13) sind ausverkauft. Der Shop nimmt sie aus der neuen Bestellung 57, die anderen Produkte darin bleiben.
Lösung
DELETE FROM order_items WHERE order_id = 57 AND product_id = 13;DELETE FROM order_items WHERE order_id = 57 AND product_id = 13. Beide Bedingungen zusammen: Ohne die erste würden die Gurken auch aus den alten Bestellungen verschwinden. Geprüft wird die ganze Tabelle order_items.
Übung
Zwei Aufgaben
1. Boris Mitev (boris.mitev@example.com) will seine Bewertungen entfernen lassen. Lösche sie und finde den Kunden mit einer Unterabfrage über die E-Mail-Adresse.
Ohne Boris' Bewertungen:
Lösung
DELETE FROM reviews
WHERE customer_id = (SELECT id FROM customers WHERE email = 'boris.mitev@example.com');DELETE FROM reviews WHERE customer_id = (SELECT id FROM customers WHERE email = 'boris.mitev@example.com'). Er hat eine Bewertung, für den Kaffee. 15 bleiben. Boris selbst lässt sich nicht löschen: Er hat Bestellungen.
2. Die Banitsa mit Käse und die Gurken sind ausverkauft und kommen vor Monatsende nicht wieder. Entferne die ausverkauften Produkte (stock 0) aus den neuen Bestellungen (status = 'new'). Die alten Bestellungen sind Verlauf und bleiben unberührt.
Die neuen Bestellungen ohne die ausverkauften Produkte:
Lösung
DELETE FROM order_items
WHERE product_id IN (SELECT id FROM products WHERE stock = 0)
AND order_id IN (SELECT id FROM orders WHERE status = 'new');DELETE FROM order_items WHERE product_id IN (SELECT id FROM products WHERE stock = 0) AND order_id IN (SELECT id FROM orders WHERE status = 'new'). Drei Zeilen verschwinden, aus den Bestellungen 27, 46 und 57. Ohne die zweite Bedingung würden 18 Zeilen verschwinden, einige aus gelieferten Bestellungen. Das Feld beginnt mit einem SELECT, das sie zeigt.
Test
Teste dich
Verwandte Lektionen
Abschnitt „Verwandte Lektionen“- Baut auf: Primärschlüssel und Fremdschlüssel · Unterabfragen · INSERT: Zeilen einfügen · UPDATE: Werte ändern
- Geht weiter in: Upsert: einfügen oder ändern · Die Datenbank: von CREATE bis DROP · Fremdschlüssel: Verbindungen zwischen Tabellen · Normalisierung
- Aufgaben zum Thema: Daten ändern