功能
MERGE INTO
语句用于根据源表或子查询中的值更新目标表中的记录。当源表包含目标表中的新行(待插入)、修改行(待更新)和删除行(待删除)时,可以使用此功能来同步目标表的数据。
语法
MERGE INTO target_table
USING source_table
ON merge_condition
{ WHEN MATCHED [ AND matched_condition ] THEN matched_action |
WHEN MATCHED [ AND matched_condition ] THEN matched_action |
--当WHEN MATCHED语句和WHEN NOT MATCHED 语句同时存在时,MERGE INTO语句中只能存在一个WHEN NOT MATCHED
WHEN NOT MATCHED [ AND not_matched_by_source_condition ] THEN not_matched_by_source_action }
-- 参数解释
matched_action ::=
UPDATE SET <column_name> = <expr> [ , <column_name2> = <expr2> ... ]
| DELETE
not_matched_action ::=
INSERT [ ( <column_name> [ , ... ] ) ] VALUES ( <expr> [ , ... ] )
参数说明
target_table
:指定目标表,可以使用别名。
source_table
:指定要与目标表进行比较的表或子查询,可以使用别名。
merge_condition
:定义如何将源表中的行与目标表中的行进行匹配,返回布尔类型的表达式。
WHEN MATCHED [ AND matched_condition ]
:当源行根据 merge_condition
和可选的 matched_condition
与目标表行匹配时,执行 WHEN MATCHED
子句。
- 如果对于匹配
merge_condition
的源行和目标行对,没有任何 WHEN MATCHED
条件的计算结果为 true,则目标行保持不变。
- 如果存在多个
WHEN MATCHED
子句,则会按照它们的指定顺序对其进行求值。每个 WHEN MATCHED
子句都必须具有一个 matched_condition
。
WHEN NOT MATCHED [ AND not_matched_condition ]
:当源行根据 merge_condition
和可选的 not_matched_condition
与目标表中的任何行都不匹配时,执行 WHEN NOT MATCHED
子句。
matched_action
:
DELETE
:删除匹配的目标表行。
UPDATE
:更新匹配的目标表行。使用 UPDATE SET column1 = source.column1 [, column2 = source.column2 ...]
。
not_matched_action
:
INSERT
:使用源数据集中的相应列插入目标表,支持指定字段插入。对于未指定的目标列,则插入为 NULL
。
注意事项
当执行 MERGE INTO
语句可能产生不确定结果时,系统会报错。产生这种情况的原因有:
- 如果
ON
子句使得源表中的多于 1 行与目标表中的行匹配,SQL 标准要求引发错误。
- 如果
ON
子句使得源表中的多于 1 行与目标表中的行匹配,同时在 AND case_predicate
条件过滤后仍有多条记录。
- 当WHEN MATCHED语句和WHEN NOT MATCHED 语句同时存在时,MERGE INTO语句中只能存在一个WHEN NOT MATCHED
确定性结果的情况:
- 如果
ON
子句使得源表中的 1 行与目标表中的行匹配。
- 如果
ON
子句使得源表中的多于 1 行与目标表中的行匹配,同时在 AND case_predicate
条件过滤后只有一条记录。
使用示例
-- 当匹配条件满足时,删除目标表中的数据
MERGE INTO target USING source
ON target.key = source.key
WHEN MATCHED THEN DELETE
-- 使用源表的 column1 更新目标表的 column1
MERGE INTO target USING source
ON target.key = source.key
WHEN MATCHED AND target.updated_at < source.updated_at THEN UPDATE SET target.col1 = source.col1
-- 如果源表和目标表的 key 匹配并且目标表中有删除标记,则删除该数据。如果 key 匹配但没有删除标记,则更新目标表
MERGE INTO target USING source
ON target.key = source.key
WHEN MATCHED AND target.marked_for_deletion THEN DELETE
WHEN MATCHED THEN UPDATE SET target.updated_at = source.updated_at, target.value = source.value
-- 插入新数据,如果 key 已存在,则更新目标表中的值
MERGE INTO target USING source
ON target.key = source.key
WHEN MATCHED THEN UPDATE SET target.col1 = source.col1, target.col2 = source.col2
WHEN NOT MATCHED THEN INSERT (col1, col2) VALUES (source.col1, source.col2)