首页 > 数据库 >T-SQL——关于数据合并(Merge)

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

时间:2023-09-12 23:44:21浏览次数:39  
标签:Name -- 2023 合并 Id Merge SQL Msg CreateTime

目录

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

0. 背景说明及测试数据

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

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

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

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


1. 直接清空,重新插入

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


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


--创建一个临时测试数据
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 准备测试数据

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

--没要合并操作前的数据
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.参考

标签:Name,--,2023,合并,Id,Merge,SQL,Msg,CreateTime
From: https://www.cnblogs.com/shanzhiming/p/17696515.html

相关文章

  • MySQL SQL语法大全
    SQL语法基础知识总结|JavaGuide(Java面试+学习指南)基本概念数据库术语数据库(database)-保存有组织的数据的容器(通常是一个文件或一组文件)。数据表(table)-某种特定类型数据的结构化清单。模式(schema)-关于数据库和表的布局及特性的信息。模式定义了数据在表中如何存储......
  • 通过SQL Server操作MySQL(下)—— 操作MySQL
    查询MySQL语句select*fromopenquery(TestMySQL,'select*fromtest.TestTable');向MySQL表中插入数据insertintoopenquery(TestMySQL,'select*fromtest.TestTable')select1,'TestName';删除MySQL表中的数据deletefromopenquery(TestMyS......
  • 【SQL Server】通过SQL Server操作MySQL(上)——连接MySQL服务器
    http://t.zoukankan.com/xd502djj-p-3104191.html 在多种数据库环境下,经常会遇见不同数据库之间转换数据或进行互相操作的情况。以下简要介绍下用SQLServer操作MySQL的步骤和方法。安装MySQL驱动想要在SQLServer中操作MySQL,首先要在SQLServer所在的服务器上安装MySQL的驱......
  • MySQL字符集详解——utf8mb4 & utf8区别?
    字符集详解|JavaGuide(Java面试+学习指南)MySQL字符编码集中有两套UTF-8编码实现:utf8和**utf8mb4**。如果使用utf8的话,存储emoji符号和一些比较复杂的汉字、繁体字就会出错。何为字符集?字符是各种文字和符号的统称,包括各个国家文字、标点符号、表情、数字等等。......
  • sql知识点
    sql知识点1.查看唯一值distinct2.筛选满足条件怎么样,不满足条件怎么样casewhen条件then(满足条件执行)else(不满足条件执行)end;(括号中可以是常量、变量、表达式也可以嵌套其他语句)casewhenA_name=''thendemoelseA_nameend;casewhennvl(b.CITY_NAME,'')......
  • Linux操作系统下安装与配置MySQL
    一、安装与配置[root@mysql1~]#cat/etc/redhat-releaseCentOSLinuxrelease7.9.2009(Core)https://downloads.mysql.com/archives/community/#下载地址[root@mysql1tools]#rpm-ivhmysql-community-client-5.7.18-1.el7.x86_64.rpm警告:mysql-community-client-5.......
  • MySQL异常断电恢复脚本
    #!/bin/bashuser="root"host="127.0.0.1"passwd="password"conf_file="/etc/mysql/mysql.conf.d/mysqld.cnf"backup_file="/home/ehigh/DB.sql"data_dir="/var/lib/mysql"if[$(id-u)-ne0];then......
  • sqlalchemy 排序方式 flask
    第一种:直接在查询语句中使用order_by现在就用第一种方法实现刚才所说(最新注册的用户的拍在前面),最新注册的也就是时间最大的。代码如下results=session.query(User).order_by(User.create_time.desc()).all()print(results)运行结果如下。 嗯,结果如我们所愿(时间按从大到小......
  • MySQL-分区表和分区介绍
    一、MySQL分区简介1、数据库分区数据库分区是一种物理数据库设计技术。虽然分区技术可以实现很多效果,但其主要目的是为了在特定的SQL操作中减少数据读写的总量以缩减sql语句的响应时间,同时对于应用来说分区完全是透明的。MYSQL的分区主要有两种形式:水平分区和垂直分区①、水平......
  • java中Mysql Insert 的高效应用
    在Java中,使用MySQL进行高效的插入操作可以采取以下几种方法:1.使用批量插入:通过使用批量插入语句,可以一次性插入多条数据,减少与数据库的交互次数,提高插入效率。可以使用JDBC的`addBatch()`方法将多个插入语句添加到批处理中,然后使用`executeBatch()`方法执行批处理。2.使用预编译......