概述
merge 关键字它能使用指定来源的数据,对目标表中的行执行 insert 、update 或 delete 操作,所有这些都符合语句中指定的条件和匹配标准。
基础语法:
merge into target_table using source_table on condition when matched [and <condition>] then operation when not matched [and <condition>] then operation;
其中最后语句分号不可以省略,且源表既可以是一个表也可以是一个子查询语句。
merge 语句通常包含 matched 或 not matched 子句,对应如何处理匹配和不匹配的场景。对于匹配子句,您可以选择在目标表上执行更新或删除操作之间进行选择。相反,在不匹配子句的情况下,可用的选择是 insert 。
因此,应用场景有数据同步和基于源表对目标表做 insert 、update 或 delete 操作。
当源表和目标表不匹配时:
若数据是源表有目标表没有,则进行插入操作;
若数据是源表没有而目标表有,则进行更新或者删除数据操作
当源表和目标表匹配时:
进行更新操作或者删除操作。
merge无法多次更新同一行,也无法更新和删除同一行。
merge 还有一些使用限制:
在 merge matched 操作中,只能允许执行 update 或者 delete 语句,并且只能出现一次,否则报错。
在 merge not matched 操作中,只允许执行 insert 语句。
数据准备
准备以下三个表用于测试。
drop table if exists employees; create table if not exists employees ( employee_id int, employee_name varchar(255), department varchar(255) ); drop table if exists salaries; create table if not exists salaries ( employee_id int, salary decimal(10, 2) ); drop table if exists target_table; create table if not exists target_table ( id int, name varchar(50), age int, city varchar(50) ); insert into employees values (1, 'Alice', 'HR'), (2, 'Bob', 'IT'), (3, 'Charlie', 'Finance'), (4, 'David', 'HR'); insert into salaries values (1, 50000.00), (2, 60000.00); insert into target_table (id, name, age, city) values (1, 'Alice', 25, 'Toronto'), (2, 'Bob', 30, 'Vancouver'), (3, 'Carol', 28, 'Montreal'); -- 开启 merge 功能 set enable_experimental_merge_into = 1;
应用示例
需求是将“员工”的员工数据同步到“工资”,允许根据指定标准插入和更新工资信息
merge into salaries using (select * from employees) as employees on salaries.employee_id = employees.employee_id when matched and employees.department = 'HR' then update set salaries.salary = salaries.salary + 1000.00 when matched then update set salaries.salary = salaries.salary + 500.00 when not matched then insert (employee_id, salary) values (employees.employee_id, 55000.00);
同步数据
create table if not exists target_table like target_table; -- 同步全量数据 merge into target_table as t using (select * from source_table) as s on t.id = s.id when matched then update * when not matched then insert *;
总结
merge 用法功能比较丰富,这里只是简单应用,如果想了解更多,可以搜索手动实践。在我们要对表做多种操作时,这种写法不仅可以节省代码,而且有时候还可以提高执行效率。
参考资料:
- Databend DML MERGE:https://docs.databend.com/sql/sql-commands/dml/dml-merge