✅ Fazit: Mit UPDATE...FROM und UPDATE...WITH (CTE) lassen sich selbst komplexe Tabellenaktualisierungen in SQL Server elegant, lesbar und performant umsetzen. Gut gewählte Indizes, Batch-Verarbeitung und die OUTPUT-Klausel runden das Repertoire für den produktiven Einsatz ab.📝 T-SQL UPDATE · JOIN, CTE & Performance
1. Einfaches UPDATE – Grundform
BASIS
-- Einfache Aktualisierung einer Spalte mit Bedingung
UPDATE Mitarbeiter
SET Gehalt = Gehalt * 1.05
WHERE AbteilungID = 5;
-- Mehrere Spalten auf einmal aktualisieren
UPDATE Produkte
SET Preis = ROUND(Preis * 1.1, 2),
LetzteAktualisierung = GETDATE()
WHERE KategorieID IN (2, 5);2. UPDATE mit JOIN – Daten aus anderer Tabelle
JOIN / FROM
-- Beispiel: Preise aus einer Preistabelle aktualisieren
UPDATE P
SET P.Preis = U.NeuPreis
FROM Produkte P
INNER JOIN PreisUpdate U ON P.Code = U.Code;
-- Alternative mit WHERE (impliziter JOIN) – aber weniger lesbar
UPDATE alt
SET alt.Name = neu.Name
FROM Person_Archiv alt, Person_Neu neu
WHERE alt.Id = neu.Id;
-- Wichtig: Aliase machen die Zieltabelle eindeutig3. UPDATE mit CTE – sauber & aggregiert
COMMON TABLE EXPRESSION
-- Beispiel: Status in Customers aktualisieren basierend auf Gesamtguthaben der BankAccounts
WITH CustomerBalances AS (
SELECT C.CustomerID, SUM(BA.Balance) AS TotalBalance
FROM Customers C
INNER JOIN BankAccounts BA ON C.CustomerID = BA.CustomerID
GROUP BY C.CustomerID
)
UPDATE C
SET C.Status = CASE
WHEN CB.TotalBalance >= 3000 THEN 'Rich'
ELSE 'Poor'
END
FROM Customers C
INNER JOIN CustomerBalances CB ON C.CustomerID = CB.CustomerID;
-- Wichtig: Die CTE muss eindeutige Zeilen referenzieren, z. B. via PRIMARY KEY4. MERGE – INSERT + UPDATE kombiniert (UPSERT)
MERGE
-- Preisliste mit MERGE verarbeiten (einfügen oder aktualisieren)
MERGE INTO Produkte AS Ziel
USING PreisUpdate AS Quelle
ON Ziel.Code = Quelle.Code
WHEN MATCHED THEN
UPDATE SET Ziel.Preis = Quelle.NeuPreis,
Ziel.LetzteAktualisierung = GETDATE()
WHEN NOT MATCHED THEN
INSERT (Code, Name, Preis, LetzteAktualisierung)
VALUES (Quelle.Code, Quelle.Name, Quelle.NeuPreis, GETDATE());
-- Quelle kann eine Tabelle, CTE, oder VALUES-Konstrukt sein5. Mehrere Tabellen in UPDATE mit JOIN
MEHRERE TABELLEN
-- Tabelle1 aus Tabelle2 und Tabelle3 aktualisieren
UPDATE t1
SET t1.SpalteA = t2.SpalteX,
t1.SpalteB = t3.SpalteY
FROM Tabelle1 t1
INNER JOIN Tabelle2 t2 ON t1.Id = t2.FremdId
INNER JOIN Tabelle3 t3 ON t1.Id = t3.FremdId
WHERE t1.Status = 'aktiv';
-- Praktisch: Kombinierte Daten aus Lookup-Tabellen
UPDATE Auftraege
SET Auftraege.KundenName = k.Name,
Auftraege.ProduktBezeichnung = p.Bezeichnung
FROM Auftraege a
INNER JOIN Kunden k ON a.KundenId = k.Id
INNER JOIN Produkte p ON a.ProduktId = p.Id;6. Performance-Tipps & Best Practices
OPTIMIERUNG
-- 1. Index auf JOIN-Spalten: Beschleunigt den Abgleich enorm
CREATE INDEX IX_Produkte_Code ON Produkte(Code);
-- 2. Begrenzung der zu aktualisierenden Zeilen (z. B. mit TOP)
UPDATE TOP (1000) LogEintraege
SET Status = 'processed'
WHERE Verarbeitet = 0;
-- 3. OUTPUT-Klausel für Kontrolle oder Auditing
UPDATE Mitarbeiter
SET Gehalt = Gehalt * 1.05
OUTPUT deleted.Gehalt AS AlterWert,
inserted.Gehalt AS NeuerWert,
inserted.MitarbeiterID
WHERE AbteilungID = 3;
-- 4. Transaktion für konsistente, mehrstufige Änderungen
BEGIN TRANSACTION;
UPDATE Bestand SET Menge = Menge - 10 WHERE ProduktID = 4711;
UPDATE Auftraege SET Status = 'versendet';
COMMIT; -- bei Fehler: ROLLBACK
📌 Wann verwende ich welche Methode?
/* Einfaches UPDATE */ → Änderung in einer Tabelle, kleiner Filter.
/* UPDATE mit JOIN */ → Werte aus einer anderen Tabelle übernehmen (z. B. Preis- oder Stammdaten).
/* UPDATE mit CTE */ → Komplexe Vorberechnung oder Aggregation, bevor aktualisiert wird.
/* MERGE (UPSERT) */ → Synchronisation zweier Tabellen (einfügen + aktualisieren in einem Schritt).
/* Mehrere Tabellen im JOIN */ → Aktualisierung aus zwei oder mehr Quelltabellen gleichzeitig.
⚠️ Besondere Vorsicht
Datenmodifikation mit JOINs · CTE · MERGE · Best Practices
UPDATE-Anweisungen mit Joins, CTEs und Unterabfragen – Daten aus anderen Tabellen effizient aktualisieren (SQL Server / Azure SQL).
⚠️ Achtung bei UPDATE ohne WHERE! Eine UPDATE-Anweisung ohne einschränkende WHERE-Klausel oder passenden JOIN aktualisiert ausnahmslos alle Zeilen der Tabelle. Verwenden Sie solche Anweisungen daher stets mit Bedacht.
📌 Wofür? Aktualisieren von Werten in einer Tabelle, entweder für alle Zeilen oder gefiltert mit WHERE.
💡 Erklärung: Die Syntax ist intuitiv: UPDATE legt die Tabelle fest, SET definiert die neuen Werte. Ein WHERE-Filter ist optional – ohne ihn werden tatsächlich alle Zeilen überschrieben.
📌 Wofür? Eine Tabelle mit Werten aus einer anderen Tabelle aktualisieren, basierend auf einer Verknüpfungsbedingung. Die FROM-Klausel definiert die Quelle, der JOIN die Beziehung.
🔗 Erklärung: Die FROM-Klausel definiert, welche weiteren Tabellen in die Aktualisierung einbezogen werden. Der JOIN legt fest, wie die Tabellen verknüpft werden. Wichtig: Sie müssen die zu aktualisierende Tabelle im UPDATE sowie erneut in der FROM-Klausel mit einem eindeutigen Alias referenzieren.
🚀 Performance-Tipp: Für große Datenmengen sollten Sie auf den verknüpften Spalten (z. B. Product.Code und PriceUpdate.Code) einen Index erstellen – das beschleunigt den Abgleich enorm.
📌 Wofür? In einer CTE können Sie komplexe Berechnungen oder Aggregationen durchführen, bevor Sie die darin enthaltenen Daten gezielt aktualisieren.
🧩 Erklärung: Common Table Expressions (CTEs) verbessern die Lesbarkeit komplexer Updates enorm. Im Beispiel wird zuerst die Gesamtsumme pro Kunde berechnet, danach wird der Status in der Tabelle Customers aktualisiert. Die CTE kann selbst direkt das Ziel des Updates sein, sofern sie keine Aggregationen oder komplexen Joins enthält.
💡 Wissenswert: Eine CTE verhält sich wie eine Sicht (View). Wenn Sie eine CTE aktualisieren, wird direkt die zugrunde liegende Basistabelle geändert.
📌 Wofür? Mit MERGE können Sie in einer einzigen Anweisung Einfügen (INSERT), Aktualisieren (UPDATE) und Löschen (DELETE) auf Basis eines Quell-Datasets kombinieren. Besonders nützlich für die Synchronisation zweier Tabellen.
🔄 Erklärung: Die MERGE-Anweisung vergleicht Ziel- und Quelltabelle anhand einer Bedingung (ON). Je nachdem, ob ein Datensatz bereits existiert oder nicht, wird entweder aktualisiert (WHEN MATCHED) oder neu eingefügt (WHEN NOT MATCHED). Das spart mehrere Einzelabfragen und reduziert den Code.
📌 Wofür? Zwei oder mehr Quelltabellen können ebenfalls in einem UPDATE genutzt werden – besonders nützlich, wenn Daten aus mehreren Quellen aggregiert werden müssen.
✨ Erklärung: Durch mehrere Joins in der FROM-Klausel ist es möglich, eine Tabelle mit Werten aus zwei oder mehreren Quellen zu aktualisieren. Der SQL Server-Optimizer löst die Joins intern auf – für ihn ist es eine natürliche Erweiterung des einfachen JOIN-Updates.
📈 Wichtige Tipps: