SQL Academy
Premium

Daten aktualisieren, der UPDATE-Operator

Einmal eingetragene Daten bleiben nicht immer richtig: Menschen ändern ihren Nachnamen, in Zahlungen tauchen Tippfehler auf, Preise müssen neu berechnet werden. Um eine Zeile zu korrigieren, ohne sie zu löschen, verwendest du den Operator UPDATE.

Allgemeine Struktur einer Query mit UPDATE

MySQL 8.4
UPDATE tabellen_name
SET tabellen_feld = wert [, ...]
[WHERE auswahl_bedingung];
  • [ ]optionaler Teil
  • ...kann wiederholt werden
tabellen_name
Die Tabelle, deren Datensätze geändert werden.
tabellen_feld

Die Spalte, die einen neuen Wert bekommt. Du kannst mehrere Paare tabellen_feld = wert durch Kommas getrennt angeben.

wert

Der neue Wert: eine Zahl, ein String, ein Ausdruck wie price * 1.1 oder NULL.

auswahl_bedingung

Welche Zeilen geändert werden. Ohne WHERE werden alle Zeilen der Tabelle geändert.

Optional

Andie (Andie Quincey) hat zum Beispiel seinen Nachnamen geändert und heißt jetzt Andie Anthony.

MySQL 8.4
UPDATE FamilyMembers
SET member_name = 'Andie Anthony'
WHERE member_name = 'Andie Quincey';
member_idstatusmember_namebirthday
1fatherHeadley Quincey1960-05-13T00:00:00.000Z
2motherFlavia Quincey1963-02-16T00:00:00.000Z
3sonAndie QuinceyAndie Anthony1983-06-05T00:00:00.000Z
4daughterLela Quincey1985-06-07T00:00:00.000Z
5
4 weitere Zeilen
daughterAnnie Quincey1988-04-10T00:00:00.000Z

Mehrere Spalten ändern

Um mehrere Spalten auf einmal zu ändern, gib nach SET mehrere Paare tabellen_feld = wert durch Kommas getrennt an. Andie hat zum Beispiel 4 Packungen Milch zu je 25 gekauft, aber in der Zahlung mit der ID 3 wurden versehentlich 5 zu je 20 eingetragen. Korrigieren wir beide Spalten mit einer Query:

MySQL 8.4
UPDATE Payments
SET amount = 4, unit_price = 25
WHERE payment_id = 3;
payment_iddatefamily_membergoodamountunit_price
12005-02-12T00:00:00.000Z1112000
22005-03-23T00:00:00.000Z2112100
32005-05-14T00:00:00.000Z34542025
42005-07-22T00:00:00.000Z451350
5
24 weitere Zeilen
2005-07-26T00:00:00.000Z472150

Alle aufgeführten Spalten ändern sich in denselben Zeilen — in denen, die die WHERE-Bedingung erfüllen.

Berechnete Werte

Einen neuen Wert kannst du aus dem alten berechnen, zum Beispiel alle Preise verdoppeln:

MySQL 8.4
UPDATE Payments
SET unit_price = unit_price * 2;

Im Ausdruck kannst du auch andere Spalten derselben Zeile verwenden, solange ihre Datentypen kompatibel sind. Erfassen wir zum Beispiel die Zahlung mit der ID 3 als eine einzige Position: In unit_price steht dann der Preis des gesamten Einkaufs und in amount eine Eins.

MySQL 8.4
UPDATE Payments
SET unit_price = unit_price * amount,
    amount = 1
WHERE payment_id = 3;

Bei einem UPDATE auf eine einzelne Tabelle werden die Zuweisungen in SET von links nach rechts ausgeführt, und der nächste Ausdruck sieht bereits den neuen Wert der Spalte. Vertauschst du die Zuweisungen, wird unit_price mit der gerade geschriebenen Eins multipliziert und bleibt unverändert:

MySQL 8.4
UPDATE Payments
SET amount = 1,
    unit_price = unit_price * amount
WHERE payment_id = 3;

Ändere deshalb eine Spalte, von der andere Ausdrücke abhängen, immer als Letztes.

Alle Ausdrücke in SET werden mit den Werten berechnet, die die Zeile vor der Änderung hatte. Die Reihenfolge der Zuweisungen spielt deshalb keine Rolle. Diese Query liefert dasselbe Ergebnis:

MySQL 8.4
UPDATE Payments
SET amount = 1,
    unit_price = unit_price * amount
WHERE payment_id = 3;

Aktualisieren anhand der Daten einer anderen Tabelle

Manchmal müssen die zu ändernden Zeilen anhand der Daten einer anderen Tabelle ausgewählt werden. Zum Beispiel hat sich herausgestellt, dass in allen Zahlungen für Kaviar nur der halbe Preis eingetragen wurde. Am einfachsten geht das mit einer Subquery in WHERE:

MySQL 8.4
UPDATE Payments
SET unit_price = unit_price * 2
WHERE good IN (
    SELECT good_id
    FROM Goods
    WHERE good_name LIKE '%caviar%'
);

Dasselbe erreichst du, indem du die Tabellen direkt in der UPDATE-Query mit JOIN verknüpfst:

MySQL 8.4
UPDATE tabellen_name_1
JOIN tabellen_name_2 ON verbund_bedingung
SET tabellen_name_1.tabellen_feld = wert [, ...]
[WHERE auswahl_bedingung];
  • [ ]optionaler Teil
  • ...kann wiederholt werden
tabellen_name_1
Die Tabelle, deren Datensätze geändert werden.
tabellen_name_2

Die verknüpfte Tabelle, anhand deren Daten die Zeilen ausgewählt und die neuen Werte berechnet werden.

verbund_bedingung

Wie die Zeilen verknüpft sind, z. B. tabellen_name_1.feld = tabellen_name_2.feld.

auswahl_bedingung

Welche Zeilen geändert werden. Die Bedingung kann Spalten beider Tabellen prüfen.

Optional
MySQL 8.4
UPDATE Payments
JOIN Goods ON Payments.good = Goods.good_id
SET Payments.unit_price = Payments.unit_price * 2
WHERE Goods.good_name LIKE '%caviar%';

Dasselbe erreichst du, indem du die zusätzlichen Tabellen nach FROM angibst:

MySQL 8.4
UPDATE tabellen_name_1
SET tabellen_feld = wert [, ...]
FROM tabellen_name_2
WHERE verbund_bedingung
[AND auswahl_bedingung];
  • [ ]optionaler Teil
  • ...kann wiederholt werden
tabellen_name_1

Die Tabelle, deren Datensätze geändert werden. Nach FROM wird sie nicht wiederholt.

tabellen_feld

Eine Spalte von tabellen_name_1. Sie wird ohne Tabellennamen angegeben.

tabellen_name_2

Eine zusätzliche Tabelle, anhand deren Daten die Zeilen ausgewählt und die neuen Werte berechnet werden.

verbund_bedingung

Wie die Zeilen verknüpft sind, z. B. tabellen_name_1.feld = tabellen_name_2.feld.

auswahl_bedingung

Eine zusätzliche Bedingung: welche der verknüpften Zeilen geändert werden.

Optional
MySQL 8.4
UPDATE Payments
SET unit_price = unit_price * 2
FROM Goods
WHERE Payments.good = Goods.good_id
    AND Goods.good_name LIKE '%caviar%';

Eine Subquery darf nicht dieselbe Tabelle lesen, die UPDATE ändert. Den Preis in Zahlungen unter dem Durchschnitt kannst du so zum Beispiel nicht verdoppeln:

MySQL 8.4
UPDATE Payments
SET unit_price = unit_price * 2
WHERE unit_price < (SELECT AVG(unit_price) FROM Payments);

Die Query bricht mit einem Fehler ab:

MySQL 8.4
ERROR 1093 (HY000): You can't specify target table 'Payments' for update in FROM clause

Umgehen kannst du diese Einschränkung, indem du die Subquery in ein weiteres SELECT einbettest. Dann wird der Durchschnittspreis zuerst berechnet und in einer temporären Tabelle abgelegt, und das Update liest aus ihr:

MySQL 8.4
UPDATE Payments
SET unit_price = unit_price * 2
WHERE unit_price < (
    SELECT avg_price
    FROM (SELECT AVG(unit_price) AS avg_price FROM Payments) AS stats
);

Typische Fehler

Vergessenes WHERE

Eine Query ohne Bedingung ändert alle Zeilen der Tabelle. Prüfe die Bedingung zuerst mit einer SELECT-Query und setze sie erst dann in UPDATE ein.

AND statt Komma in SET

Die folgende Query ändert nicht zwei Spalten: Alles rechts vom ersten = gilt als ein einziger logischer Ausdruck.

MySQL 8.4
UPDATE Payments
SET amount = 4 AND unit_price = 25
WHERE payment_id = 3;

Die Query läuft ohne Fehler durch und schreibt das Ergebnis dieses Ausdrucks — 0 oder 1 — in amount, während unit_price unverändert bleibt.

Die Query bricht mit einem Fehler ab:

MySQL 8.4
ERROR: argument of AND must be type boolean, not type integer

Um beide Spalten zu ändern, trennst du die Zuweisungen durch ein Komma. Daran erkennt SET, wo eine endet und die nächste beginnt:

MySQL 8.4
UPDATE Payments
SET amount = 4, unit_price = 25
WHERE payment_id = 3;

Vergleich mit NULL über =

Die Bedingung WHERE feld = NULL trifft auf keine Zeile zu, deshalb ändert die Query nichts. Um auf einen leeren Wert zu prüfen, verwende IS NULL.

Prüf dich selbst

Bei einigen Nutzern in der Tabelle Users fehlt das Datum der E-Mail-Bestätigung: Das Feld email_verified_at ist NULL. Wie viele Zeilen ändert diese Query?

MySQL 8.4
UPDATE Users
SET email_verified_at = '2024-01-01'
WHERE email_verified_at = NULL;