✅ 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