SQL MERGE (auch Upsert genannt) synchronisiert in einem einzigen Statement eine Zieltabelle mit einer Quelltabelle: Zeilen, die es schon gibt, werden aktualisiert, fehlende werden eingefügt – und optional können überschüssige gelöscht werden. Statt drei getrennter Befehle reicht ein MERGE.

Grundform

Das Statement vergleicht die Quelltabelle über eine Bedingung mit der Zieltabelle und führt je nach Treffer unterschiedliche Aktionen aus:

MERGE INTO ziel t
USING quelle q
ON (t.id = q.id)
WHEN MATCHED THEN UPDATE SET t.name = q.name
WHEN NOT MATCHED THEN INSERT (id, name) VALUES (q.id, q.name);
  • USING: die Quelle (Tabelle, View oder Unterabfrage)
  • ON: die Abgleichbedingung, ähnlich wie bei einem JOIN
  • WHEN MATCHED: Zeile existiert bereits → UPDATE
  • WHEN NOT MATCHED: Zeile fehlt → INSERT
  • WHEN NOT MATCHED BY SOURCE: Zeile nur im Ziel → DELETE (SQL Server)

Verbreitung

MERGE wurde mit dem SQL-Standard SQL:2003 eingeführt und in SQL:2008 erweitert. Oracle beherrscht MERGE seit 9i (2001), SQL Server seit 2008, PostgreSQL erst seit Version 15 (2022). MySQL und MariaDB haben kein MERGE – dort übernimmt INSERT ... ON DUPLICATE KEY UPDATE die Upsert-Rolle (siehe SQL INSERT).

Vorsicht

  • Bei mehreren Quellzeilen je Zielschlüssel bricht MERGE mit einem Fehler ab – die Quelle muss je Schlüssel eindeutig sein.
  • Das Statement sperrt mehr Zeilen als vergleichbare Einzelbefehle; unter hoher Parallelität kann es zu Deadlocks kommen.
  • SQL Server kennt die MERGE-Bugs-Diskussion: In einigen Versionen traten Race Conditions mit OUTPUT und Triggers auf – MERGE ist nicht automatisch besser als explizites UPDATE + INSERT.

Typische Anwendung: Staging-Tabellen in Data-Warehouse-Läufen oder Synchronisation zwischen Datenbanken. Für die anschließende Berichtsaufbereitung werden die so geladenen Daten oft mit PIVOT (Zeilen zu Spalten) oder UNPIVOT (Spalten zu Zeilen) umgeformt.