DatabaseStatusSyntax FamilyMin Version
PostgreSQL full sql-standard-merge 15
MySQL none - -
MariaDB none - -
Oracle full sql-standard-merge -
SQL Server full sql-standard-merge 2008
SQLite none - -
Redshift full sql-standard-merge -
DB2 full sql-standard-merge -
Snowflake full sql-standard-merge -
BigQuery full sql-standard-merge -

Compare Databases

Database Details

PostgreSQL full
MERGE INTO inventory AS t
USING daily_deltas AS s ON t.product_id = s.product_id
WHEN MATCHED AND s.delta < 0 THEN
  DELETE
WHEN MATCHED THEN
  UPDATE SET quantity = t.quantity + s.delta
WHEN NOT MATCHED THEN
  INSERT (product_id, quantity) VALUES (s.product_id, s.delta);
  • Added in PostgreSQL 15.
  • Supports multiple WHEN MATCHED clauses with conditions.
  • WHEN NOT MATCHED BY SOURCE clause (for target rows with no match) added in PostgreSQL 17.
Docs: MERGE
MySQL none
  • MySQL does not support the MERGE statement.
  • Use INSERT ... ON DUPLICATE KEY UPDATE for simple upserts.
  • For more complex scenarios use a DELETE + INSERT pattern within a transaction.
MariaDB none
  • MariaDB does not support the MERGE statement.
  • Use INSERT ... ON DUPLICATE KEY UPDATE or INSERT OR REPLACE for upsert patterns.
Oracle full
MERGE INTO inventory t
USING daily_deltas s ON (t.product_id = s.product_id)
WHEN MATCHED THEN UPDATE SET t.quantity = t.quantity + s.delta
WHEN NOT MATCHED THEN INSERT (product_id, quantity) VALUES (s.product_id, s.delta);
  • Available since Oracle 9i.
  • Supports WHEN MATCHED, WHEN NOT MATCHED, conditional UPDATE/DELETE, and a DELETE sub-clause within WHEN MATCHED.
  • Error logging can be added via LOG ERRORS clause.
Docs: MERGE
SQL Server full
MERGE INTO inventory AS t
USING daily_deltas AS s ON t.product_id = s.product_id
WHEN MATCHED THEN UPDATE SET t.quantity = t.quantity + s.delta
WHEN NOT MATCHED BY TARGET THEN INSERT (product_id, quantity) VALUES (s.product_id, s.delta)
WHEN NOT MATCHED BY SOURCE THEN DELETE;
  • Available since SQL Server 2008.
  • Statement must end with a semicolon.
  • Supports OUTPUT clause for RETURNING-like behavior.
  • Supports WHEN NOT MATCHED BY SOURCE for rows present in the target but not the source.
  • Has had concurrency bugs in older versions; apply current patches.
SQLite none
  • SQLite does not support the MERGE statement.
  • Use INSERT ... ON CONFLICT for upsert behavior.
Redshift full
MERGE INTO inventory
USING daily_deltas ON inventory.product_id = daily_deltas.product_id
WHEN MATCHED THEN UPDATE SET quantity = inventory.quantity + daily_deltas.delta
WHEN NOT MATCHED THEN INSERT (product_id, quantity) VALUES (daily_deltas.product_id, daily_deltas.delta);
  • MERGE added to Redshift in 2023.
  • Supports WHEN MATCHED THEN UPDATE/DELETE and WHEN NOT MATCHED THEN INSERT.
  • Source can be a table, subquery, or VALUES list.
Docs: MERGE
DB2 full
MERGE INTO inventory AS t
USING daily_deltas AS s ON t.product_id = s.product_id
WHEN MATCHED THEN UPDATE SET t.quantity = t.quantity + s.delta
WHEN NOT MATCHED THEN INSERT (product_id, quantity) VALUES (s.product_id, s.delta);
  • Full SQL-standard MERGE support.
  • Supports multiple WHEN MATCHED clauses with conditions.
  • Supports SIGNAL to raise errors from within a MERGE action.
Docs: MERGE
Snowflake full
MERGE INTO inventory AS t
USING daily_deltas AS s ON t.product_id = s.product_id
WHEN MATCHED THEN UPDATE SET t.quantity = t.quantity + s.delta
WHEN NOT MATCHED THEN INSERT (product_id, quantity) VALUES (s.product_id, s.delta);
  • Full MERGE support.
  • Supports multiple WHEN MATCHED clauses with conditions.
  • Also supports DML error handling via error tables.
Docs: MERGE
BigQuery full
MERGE INTO inventory AS t
USING daily_deltas AS s ON t.product_id = s.product_id
WHEN MATCHED THEN UPDATE SET t.quantity = t.quantity + s.delta
WHEN NOT MATCHED THEN INSERT (product_id, quantity) VALUES (s.product_id, s.delta);
  • Full MERGE support.
  • Source and target must be different tables.
  • Supports WHEN NOT MATCHED BY SOURCE for target-only rows.
  • MERGE is atomic within a transaction.