MERGE INTO

Description

The MERGE INTO statement merges a source table or query into a target table. Rows of the target table are matched against the source using a merge condition. Target rows are then updated or deleted, and new rows are inserted from the source, according to the clauses that apply. All of these row-level changes are performed as a single atomic operation.

MERGE INTO is supported on tables backed by Data Source V2 connectors that support row-level operations.

Syntax

MERGE INTO target_table [ [ AS ] target_alias ]
    USING { source_table | ( source_query ) } [ [ AS ] source_alias ]
    ON merge_condition
    [ WHEN MATCHED [ AND matched_condition ] THEN matched_action ] [ ... ]
    [ WHEN NOT MATCHED [ BY TARGET ] [ AND not_matched_condition ] THEN not_matched_action ] [ ... ]
    [ WHEN NOT MATCHED BY SOURCE [ AND not_matched_by_source_condition ] THEN not_matched_by_source_action ] [ ... ]

matched_action
    { DELETE | UPDATE SET * | UPDATE SET { column = value } [ , ... ] }

not_matched_action
    { INSERT * | INSERT ( column [ , ... ] ) VALUES ( value [ , ... ] ) }

not_matched_by_source_action
    { DELETE | UPDATE SET { column = value } [ , ... ] }

Parameters

Note:

Examples

The following examples assume that the target and source tables have already been created and populated as shown below. Each example starts from this initial state.

SELECT * FROM target;
+--+------+-------+
|pk|salary|    dep|
+--+------+-------+
| 1|   300|     hr|
| 2|   160|    eng|
| 5|   100|finance|
+--+------+-------+

SELECT * FROM source;
+--+------+-----+
|pk|salary|  dep|
+--+------+-----+
| 1|   350|   hr|
| 2|   200|  eng|
| 3|   120|sales|
+--+------+-----+

Update Matched Rows and Insert New Rows

MERGE INTO target t
    USING source s
    ON t.pk = s.pk
    WHEN MATCHED THEN UPDATE SET *
    WHEN NOT MATCHED THEN INSERT *;

SELECT * FROM target;
+--+------+-------+
|pk|salary|    dep|
+--+------+-------+
| 1|   350|     hr|
| 2|   200|    eng|
| 3|   120|  sales|
| 5|   100|finance|
+--+------+-------+

Conditional Delete, Update, and Insert

-- Delete matched rows whose source salary exceeds 300, update the remaining matched rows,
-- and insert source rows that do not match any target row.
MERGE INTO target t
    USING source s
    ON t.pk = s.pk
    WHEN MATCHED AND s.salary > 300 THEN DELETE
    WHEN MATCHED THEN UPDATE SET salary = s.salary
    WHEN NOT MATCHED THEN INSERT (pk, salary, dep) VALUES (s.pk, s.salary, s.dep);

SELECT * FROM target;
+--+------+-------+
|pk|salary|    dep|
+--+------+-------+
| 2|   200|    eng|
| 3|   120|  sales|
| 5|   100|finance|
+--+------+-------+

Delete Target Rows Not Present in the Source

MERGE INTO target t
    USING source s
    ON t.pk = s.pk
    WHEN MATCHED THEN UPDATE SET *
    WHEN NOT MATCHED THEN INSERT *
    WHEN NOT MATCHED BY SOURCE THEN DELETE;

SELECT * FROM target;
+--+------+-----+
|pk|salary|  dep|
+--+------+-----+
| 1|   350|   hr|
| 2|   200|  eng|
| 3|   120|sales|
+--+------+-----+

Update Target Rows Not Present in the Source

MERGE INTO target t
    USING source s
    ON t.pk = s.pk
    WHEN NOT MATCHED BY SOURCE THEN UPDATE SET dep = 'unassigned';

SELECT * FROM target;
+--+------+----------+
|pk|salary|       dep|
+--+------+----------+
| 1|   300|        hr|
| 2|   160|       eng|
| 5|   100|unassigned|
+--+------+----------+