MERGE语句的使用(同步数据)

本文深入解析SQLServer中的MERGE语法,演示如何通过一条语句实现INSERT、UPDATE和DELETE操作,适用于数据同步场景,如学生信息管理系统与成绩管理系统间的数据更新。

最近学习了SQL Server这个牛逼轰轰的语法,个人认为很牛逼。
牛逼之处: MERGE语法可以将简单的INSERT,DELETE,UPDATE语句融合到一条语句中。
使用要领: MERGE语法必须作用于 两个数据源(数据表,子查询,视图) 之间
语句结构分析:
MERGE 目标表
USING 数据源(数据表,子查询,视图)
ON 匹配条件
WHEN MATCH THEN 操作语句 ;(结束的这个分号必不可少)
这就是一个简单的MERGE语句。
案例分析(场景为数据同步):
先来模拟一个场景:就清华大学吧,有一个内部级别很高的学生信息管理系统,每一名入校新生的详细信息都将被采集到这个系统中,这些信息存储在TB_STUDENT_DETAIL表中;学校还有一个学生成绩管理系统,这个系统中有一个表TB_STUDENT,只存储了学生的基本信息,并且这些信息是固定时间从学生信息管理系统中同步过来的。

现在由于新生入校和误操作等原因,我们要把学生成绩管理系统的TB_STUDENT表缺失的信息从学生信息管理系统的TB_STUDENT_DETAIL表中同步过来,现在两张表的数据如下:

数据初始化:

CREATE TABLE TB_STUDENT_DETAIL (No VARCHAR(10),NAME VARCHAR(100),AGE INT,ADDRESS VARCHAR(100),MOBILE VARCHAR(11))

INSERT INTO TB_STUDENT_DETAIL VALUES('001','张三',23,'朝阳区','12345678901')
INSERT INTO TB_STUDENT_DETAIL VALUES('002','李四',25,'海淀区','12345678901')
INSERT INTO TB_STUDENT_DETAIL VALUES('003','王五',26,'西城区','12345678901')
INSERT INTO TB_STUDENT_DETAIL VALUES('005','马六',25,'东城区','12345678901')

CREATE TABLE TB_STUDENT (No VARCHAR(10),NAME VARCHAR(100),AGE INT)

--INSERT INTO TB_STUDENT_DETAIL VALUES('001','张三',24)
INSERT INTO TB_STUDENT VALUES('001','',24)
INSERT INTO TB_STUDENT VALUES('002','',25)
INSERT INTO TB_STUDENT VALUES('003','',26)
INSERT INTO TB_STUDENT VALUES('004','宋小宝',12)

在这里插入图片描述

需求一、部分信息缺失的学生信息补全(例如上图中的学号为001,002,003的学生姓名丢失,需要补全)

MERGE TB_STUDENT T				--目标表(需要执行插入、修改、删除操作的表)
USING TB_STUDENT_DETAIL S		--数据源
ON T.No=S.No					--匹配条件
WHEN MATCHED THEN UPDATE SET T.NAME=S.NAME;		--需要修改的字段(数据源中有001,002,003,目标表中也有,则根据数据源中的NAME修改目标表的NAME字段)
--执行这条语句后再次查询两张表的数据

在这里插入图片描述
可以看到TB_STUDENT表中学号为001,002,003的学生的姓名已经被这条语句从TB_STUDENT_DETAIL表中同步了过来。

需求二、新生信息导入(TB_STUDENT_DETAIL表中,学号为005的马六同学的信息在TB_STUDENT中根本不存在,我们需要INSERT进来)

MERGE TB_STUDENT T				--目标表(需要执行插入、修改、删除操作的表)
USING TB_STUDENT_DETAIL S		--数据源
ON T.No=S.No					--匹配条件
WHEN NOT MATCHED THEN INSERT VALUES(S.No,S.NAME,S.AGE);		--数据源中有005,目标表中没有,则将这条学生信息插入到目标表中
--执行这条语句后再次查询两张表的数据

在这里插入图片描述
可以看到TB_STUDENT_DETAIL表中的新生005马六同学已经被插入到TB_STUDENT表中

需求三、将TB_STUDENT_DETAIL表中不存在而TB_STUDENT表中存在的已退学学生004宋小宝同学的信息删除

MERGE TB_STUDENT T				--目标表(需要执行插入、修改、删除操作的表)
USING TB_STUDENT_DETAIL S		--数据源
ON T.No=S.No					--匹配条件
WHEN NOT MATCHED BY SOURCE THEN DELETE;		--数据源中没有004宋小宝,而目标表中有,该学生已退学,需要删除信息(本例中只有一条,其实只要目标表中有的,而数据源中没有的都将会被删除)
--执行这条语句后再次查询两张表的数据

在这里插入图片描述

终极需求、现在以上的三步操作分开执行显得很麻烦,而且执行效率不高,我们需要使用一条sql语句完成这三步操作

这个时候MERGE语句的作用就发挥出来了,我们再次初始化数据到最初状态:

DROP TABLE TB_STUDENT 
DROP TABLE TB_STUDENT_DETAIL

CREATE TABLE TB_STUDENT_DETAIL (No VARCHAR(10),NAME VARCHAR(100),AGE INT,ADDRESS VARCHAR(100),MOBILE VARCHAR(11))

INSERT INTO TB_STUDENT_DETAIL VALUES('001','张三',23,'朝阳区','12345678901')
INSERT INTO TB_STUDENT_DETAIL VALUES('002','李四',25,'海淀区','12345678901')
INSERT INTO TB_STUDENT_DETAIL VALUES('003','王五',26,'西城区','12345678901')
INSERT INTO TB_STUDENT_DETAIL VALUES('005','马六',25,'东城区','12345678901')

CREATE TABLE TB_STUDENT (No VARCHAR(10),NAME VARCHAR(100),AGE INT)

--INSERT INTO TB_STUDENT_DETAIL VALUES(1,'张三',24)
INSERT INTO TB_STUDENT VALUES('001','',24)
INSERT INTO TB_STUDENT VALUES('002','',25)
INSERT INTO TB_STUDENT VALUES('003','',26)
INSERT INTO TB_STUDENT VALUES('004','宋小宝',12)

SELECT * FROM TB_STUDENT_DETAIL
SELECT * FROM TB_STUDENT
--现在数据已经初始化完成,如下图:

在这里插入图片描述

现在将以上的UPDATE,INSERT,DELETE三条语句整合为一条MERGE语句:

MERGE TB_STUDENT T				--目标表(需要执行插入、修改、删除操作的表)
USING TB_STUDENT_DETAIL S		--数据源
ON T.No=S.No					--匹配条件
WHEN MATCHED THEN UPDATE SET T.NAME=S.NAME		--需要修改的字段(数据源中有001,002,003,目标表中也有,则根据数据源中的NAME修改目标表的NAME字段)
WHEN NOT MATCHED THEN INSERT VALUES(S.No,S.NAME,S.AGE)		--数据源中有005,目标表中没有,则将这条学生信息插入到目标表中
WHEN NOT MATCHED BY SOURCE THEN DELETE;		--数据源中没有004宋小宝,而目标表中有,该学生已退学,需要删除信息(本例中只有一条,其实只要目标表中有的,而数据源中没有的都将会被删除)
--执行这条语句后再次查询两张表的数据

在这里插入图片描述

看一下MERGE语句的执行结果:

①目标表和数据源中都有的学号为001,002,003学生的NAME字段已经被从TB_STUDENT_DETAIL同步到了TB_STUDENT表中。
②数据源中的新生005马六同学在目标表TB_STUDENT表中并没有,但是此刻已经被同步到了TB_STUDENT表中。
③目标表中的004宋小宝同学已经退学,在数据源中并没有,需要删除,语句执行后也已经删除了。

语法分析
MERGE 目标表
USING 数据源(数据表,子查询,视图)
ON 匹配条件
WHEN MATCH THEN 操作语句(数据源和目标数据匹配上的数据,可以像案例中执行update,也可以执行delete操作,例如案例中的001,002,003)
WHEN NOT MATCH THEN 操作语句(也可以写成WHEN NOT MATCH BY TARGET THEN,指数据源中有的,而目标表中没有的数据,可以执行insert操作,例如案例中的005)
WHEN NOT MATCH BY SOURCE THEN 操作语句(指数据源中没有,而目标表中有的数据,可以执行delete操作,例如案例中的004)
(结束的这个分号必不可少)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值