T-SQL——关于数据合并(Merge)

目录

  • [0. 背景说明及测试数据](#0. 背景说明及测试数据)
  • [1. 直接清空,重新插入](#1. 直接清空,重新插入)
  • [2. 单条记录执行插入、更新操作](#2. 单条记录执行插入、更新操作)
  • [3. Merge函数](#3. Merge函数)
    • [3.1 准备测试数据](#3.1 准备测试数据)
    • [3.2 测试Merge](#3.2 测试Merge)
    • [3.3 关于Merge](#3.3 关于Merge)
  • 4.参考

shanzm-2023年9月12日 21:09:04


0. 背景说明及测试数据

什么是合并?

根据记录是否已经存在,决定是否插入、更新或删除

简单说明,数据库需要将某个表A的数据同步到指定的表B中,

表A和表B中字段一样,都有一样的唯一键,需要同时实现一下三种操作:

  • 若表A中某条数据在表B中不存在,则在表中插入该条数据
  • 若表A中某条数据在表B中存在,但是某些字段值不一样,则对表B进行更改
  • 若表B中存在某条数据在表A中不存在,则删除表B中的该条记录

1. 直接清空,重新插入

  • 简单粗暴:将表B清空,之后将表A中数据全部插入,即实现了上述三操作
    • 此法并非万能,若是在数据库中清洗数据的时候可以这么做,但是程序中不建议
sql 复制代码
TRUNCATE TABLE tbB
INSERT INTO	tbB SELECT * FROM  tbA

2. 单条记录执行插入、更新操作

sql 复制代码
--创建一个临时测试数据
IF OBJECT_ID('tempdb..#temp') IS NOT NULL BEGIN
    DROP TABLE #temp;
END;

CREATE TABLE #temp (Id INT, Name VARCHAR(10), CreateTime DATETIME);
INSERT INTO #temp(Id, Name, CreateTime)
VALUES(1, '张三', '2023-6-1 15:20:31'),
    (2, '李四', '2023-6-1 15:25:53');

--不存在Id=2的记录则插入
IF NOT EXISTS (SELECT * FROM #temp WHERE Id=2)
BEGIN
    INSERT INTO #temp(Id, Name, CreateTime)VALUES(2, '张三', GETDATE());
END;
--存在Id=2的记录则更新
ELSE 
BEGIN
    UPDATE #temp SET Name='李四', CreateTime=GETDATE()WHERE Id=2;
END;
SELECT * FROM #temp;

3. Merge函数

3.1 准备测试数据

sql 复制代码
IF OBJECT_ID('tempdb..#tempA') IS NOT NULL
    DROP TABLE #tempA;
CREATE TABLE #tempA
(
    [Id] INT,
    [Name] VARCHAR(4),
    [Msg] VARCHAR(100),
    [CreateTime] DATETIME
);
INSERT INTO #tempA
(
    [Id],
    [Name],
    [Msg],
    [CreateTime]
)
VALUES
(1, '张三', '这是要插入的', N'2023-03-31'),
(2, '李四', '这是要更新的', N'2023-03-31');

SELECT * FROM #tempA;

--结果:

Id          Name     Msg                  CreateTime
----------- ---- --------------------   -----------------
1           张三   这是要插入的               2023-03-31 
2           李四   这是要更新的               2023-03-31 



IF OBJECT_ID('tempdb..#tempB') IS NOT NULL
    DROP TABLE #tempB;
CREATE TABLE #tempB
(
    [Id] INT,
    [Name] VARCHAR(4),
    [Msg] VARCHAR(100),
    [CreateTime] DATETIME
);
INSERT INTO #tempB
(
    [Id],
    [Name],
    [Msg],
    [CreateTime]
)
VALUES
(2, '李四', '这是要被更新的', N'2023-01-31'),
(3, '张三', '这是要被删除的', N'2023-01-31');

SELECT * FROM #tempB;

--结果:
Id          Name     Msg                  CreateTime
----------- ---- --------------------   ----------------
2           李四   这是要被更新的              2023-01-31 
3           张三   这是要被删除的              2023-01-31 

3.2 测试Merge

sql 复制代码
--没要合并操作前的数据
SELECT * FROM #tempB

MERGE INTO	 #tempB AS T--目标表
USING #tempA AS S--源表
ON T.Id=S.Id
WHEN MATCHED --当满足 T.Id=S.Id条件时候
THEN	UPDATE SET T.Name=S.Name, T.Msg=s.Msg,T.CreateTime=S.CreateTime
WHEN NOT MATCHED--当目标表中没有该Id,而源表中有,则插入
THEN	 INSERT VALUES(S.Id,S.Name, S.Msg,S.CreateTime)
WHEN NOT MATCHED BY SOURCE--当目标表中存在,源表中不存在,则删除
THEN	DELETE;
--OUTPUT $action AS[ACTION],Inserted.Id AS [插入的Id],Inserted.Msg AS 插入的Msg,Deleted.Id AS 删除的Id,Deleted.Msg AS 删除的Msg;--输出各个操作

--合并操作后的数据
SELECT * FROM #tempB


--结果

--原始数据
Id          Name    Msg                  CreateTime
----------- ---- -------------------- -----------------------
2           李四   这是要被更新的              2023-01-31 
3           王五   这是要被删除的              2023-01-31 


--Merge后的数据
Id          Name    Msg                  CreateTime
----------- ---- -------------------- -----------------------
2           李四   这是要更新的               2023-03-31 
1           张三   这是要插入的               2023-03-31 

3.3 关于Merge

  • 若原表中出现重复记录,而该记录是目标表中没有的,则会将所有的重复记录插入到目标中
  • Merge关键字后面使用了多个WHEN......THEN,是可选的,可以是紧紧新增或仅仅删除
  • 目标表和源表可以是一个查询结果集

4.参考

相关推荐
Zda天天爱打卡2 小时前
【趣学SQL】第二章:高级查询技巧 2.2 子查询的高级用法——SQL世界的“俄罗斯套娃“艺术
数据库·sql
苏-言3 小时前
MyBatis最佳实践:动态 SQL
数据库·sql·mybatis
Amd79411 小时前
深入探讨存储过程的创建与应用:提高数据库管理效率的关键工具
sql·性能优化·数据安全·存储过程·数据库管理·业务逻辑·创建存储过程
MrZhangBaby14 小时前
SQL-leetcode—1158. 市场分析 I
java·sql·leetcode
摘星怪sec17 小时前
【漏洞复现】|方正畅享全媒体新闻采编系统reportCenter.do/screen.do存在SQL注入
数据库·sql·web安全·媒体·漏洞复现
十二同学啊17 小时前
JSqlParser:Java SQL 解析利器
java·开发语言·sql
莫名有雪17 小时前
BUUCTF_Web([RCTF2015]EasySQL)二次注入+报错注入
sql
m0_7482370520 小时前
sql实战解析-sum()over(partition by xx order by xx)
数据库·sql
羊小猪~~1 天前
MYSQL学习笔记(四):多表关系、多表查询(交叉连接、内连接、外连接、自连接)、七种JSONS、集合
数据库·笔记·后端·sql·学习·mysql·考研
村口蹲点的阿三1 天前
Spark SQL 中对 Map 类型的操作函数
javascript·数据库·hive·sql·spark