MERGE Statement
Conditionally INSERT, UPDATE, or DELETE rows in a target table based on a join with a source.
MERGE MERGE INTO UPSERT SQL:2003 MERGE WHEN MATCHED WHEN NOT MATCHED
merge insert update delete conditional dml
| Database | Status | Syntax Family | Min 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.
Docs: MERGE (Transact-SQL)
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.
Docs: MERGE statement