首页 > 数据库 >SQL Server MERGE(合并)语句

SQL Server MERGE(合并)语句

时间:2024-01-31 18:15:08浏览次数:35  
标签:category 语句 表中 sales Server MERGE SQL MATCHED

来源 https://www.cnblogs.com/yigegaozhongsheng/p/11941734.html

如何使用SQL Server MERGE语句基于与另一个表匹配的值来更新表中的数据。

 

 SQL Server MERGE语句

 

假设有两个表,分别称为源表和目标表,并且需要根据与源表匹配的值来更新目标表。有以下三种情况:

 

  1. 源表中有一些目标表中不存在的行。在这种情况下,需要将源表中的行插入目标表中。
  2. 目标表中的某些行在源表中不存在。在这种情况下,需要从目标表中删除行。
  3. 源表中的某些行与目标表中的行具有相同的键。但是,这些行在非键列中具有不同的值。在这种情况下,需要使用源表中的值更新目标表中的行。

 

下图说明了源表和目标表以及相应的操作:插入,更新和删除:

 

 

 

 

 如果使用INSERT,UPDATE以及DELETE单独的语句,你必须建立三个单独的语句从源表匹配的行更新数据到目标表。

 

但是,SQL Server提供了MERGE允许同时执行三个操作的语句。下面显示了该MERGE语句的语法:

 

复制代码
MERGE target_table USING source_table
ON merge_condition
WHEN MATCHED
    THEN update_statement
WHEN NOT MATCHED
    THEN insert_statement
WHEN NOT MATCHED BY SOURCE
    THEN DELETE;
复制代码

 

首先,在MERGE子句中指定目标表和源表。

 

其次,merge_condition确定源表中的行与目标表中的行如何匹配。它类似于join子句中的join条件。通常,使用主键或唯一键的键列进行匹配。

 

三,merge_condition结果有三种状态:MATCHED,NOT MATCHED,和NOT MATCHED BY SOURCE。

 

MATCHED:这些是符合合并条件的行。对于匹配的行,需要使用源表中的值更新目标表中的行列。

NOT MATCHED:这些是源表中的行,目标表中没有任何匹配的行。在这种情况下,需要将源表中的行添加到目标表中。请注意,NOT MATCHED也称为NOT MATCHED BY TARGET。

NO MATCHED BY SOURCE:这些是目标表中的行,与源表中的任何行都不匹配。如果要使目标表与源表中的数据同步,则需要使用此匹配条件从目标表中删除行。

 

SQL Server MERGE语句示例

 

假设我们有两个表,sales.category并且sales.category_staging按产品类别存储销售额。

复制代码
CREATE TABLE sales.category (
    category_id INT PRIMARY KEY,
    category_name VARCHAR(255) NOT NULL,
    amount DECIMAL(10 , 2 )
);
 
INSERT INTO sales.category(category_id, category_name, amount)
VALUES(1,'自行车',15000),
    (2,'摩托车',25000),
    (3,'汽车',13000),
    (4,'火车',10000);
 
 
CREATE TABLE sales.category_staging (
    category_id INT PRIMARY KEY,
    category_name VARCHAR(255) NOT NULL,
    amount DECIMAL(10 , 2 )
);
 
 
INSERT INTO sales.category_staging(category_id, category_name, amount)
VALUES(1,'自行车',15000),
    (3,'汽车',13000),
    (4,'火车',20000),
    (5,'飞机',10000),
    (6,'火箭',10000);
复制代码

要使用(源表)中sales.category的值将数据更新到(目标sales.category_staging表),使用以下MERGE语句:

 

复制代码
MERGE sales.category t 
    USING sales.category_staging s
ON (s.category_id = t.category_id)
WHEN MATCHED
    THEN UPDATE SET 
        t.category_name = s.category_name,
        t.amount = s.amount
WHEN NOT MATCHED BY TARGET 
    THEN INSERT (category_id, category_name, amount)
         VALUES (s.category_id, s.category_name, s.amount)
WHEN NOT MATCHED BY SOURCE 
    THEN DELETE;
复制代码

 

SQL Server合并示例

 

在此示例中,我们将category_id两个表中的列中的值用作合并条件。

  • 首先,sales.category_staging表中ID为1、3、4的行与目标表中的行匹配,因此,该MERGE语句更新了表中类别名称和数量列中的值sales.category。
  • 其次,sales.category_staging表中ID为5和6的行在表中不存在sales.category,因此该MERGE语句将这些行插入到目标表中。
  • 第三,sales.category表中ID为2的行在表中不存在sales.sales_staging,因此,该MERGE语句删除了该行。

 

 

合并的结果是,sales.category表中的数据与sales.category_staging表中的数据完全同步  。

标签:category,语句,表中,sales,Server,MERGE,SQL,MATCHED
From: https://www.cnblogs.com/provedl/p/17999847

相关文章

  • 使用 PyQt5(PySide2)+SQLAlchemy 做一个登录注册页(一)
    使用PyQt5(PySide2)+SQLAlchemy做一个登录注册页(一)本文将介绍自己用PyQt5+SQLAlchemy做的一个登录注册页,使用邮箱接收验证码,本文介绍是前后端未分离的实现方式,后续将出一个前后端分离的,你可以将PyQt5改为PySide2以获得更宽松的开源协议本文由于涉及到的代码较多,将会是......
  • golang 正则过滤sql注入的方法
    该方法返回的是一个bool值packagemainimport"regexp"import"fmt"//正则过滤sql注入的方法//参数:要匹配的语句funcFilteredSQLInject(to_match_strstring)bool{//过滤‘//ORACLE注解--/**///关键字过滤update,delete//正则的字符......
  • MySQL介绍
    数据库的由来和基本概念什么是数据库?|Oracle中国【一】数据的发展史早期未出现互联网前,每个人都只可以在本地存储,且存储的数据格式都是根据每个人的需要自由定义的出现网络后,可以在局域网内进行多台计算机的数据共享,而这时,数据的格式只能由人为约束,约定俗成好一套数据存......
  • Socket.D v2.3.9 发布(增加 node.js server 实现)
    Socket.D是基于"事件"和"语义消息""流"的网络应用层传输协议。有用户说,“Socket.D之于Socket,尤如Vue之于Js、Mvc之于Http”。支持tcp,udp,ws,kcp传输。协议特点可参考《官网介绍》。pyton已开发完成,再在测试中;go,rust,c++正在开发中。forJava适配框架更新说......
  • Mysql中存储引擎InnoDB,MyISAM,MEMORY比较
    Mysql中存储引擎InnoDB,MyISAM,MEMORY比较showENGINES--查看数据库支持的搜索引擎ENGINE=InnoDB--使用的InnoDB引擎CREATETABLE`user1`(`id`bigint(20)NOTNULLDEFAULT'0',`name`varchar(255)DEFAULTNULL,`age`int(11)DEFAULTNULL,`sex`varchar(255)......
  • MYSQL日志
    要开启MySQL的二进制日志(binlog),需按照以下步骤进行操作:1.打开MySQL配置文件:首先,找到MySQL的配置文件my.cnf(或my.ini,视操作系统而定)。2.找到并修改binlog相关配置:在配置文件中找到以下几个参数,如果没有则手动添加:[mysqld]log-bin=mysql-bin#开启binlog,设置binlog......
  • MySQL大表分页查询的坑以及解决方案
    最近在做一个需求,需求内容中有一个功能点是查询指定用户标签里的用户id,这里做了分页查询,分页查询是用mysql的LIMIT设置offset和size值来实现的。在程序执行过程中会发现,如果查询的用户标签数据量很大时会出现慢查询告警,这里已经对mysql表的标签名称和用户id字段都加了索引,并且limi......
  • 数据库研发人员必看的MySQL 8.0新特性
    本文汇总了MySQL8.0面向开发的新特性,总共有12个新特性,有想快速了解8.0新特性的朋友,可以看一下哈文章目录:1.公用表达式支持-CTE2.窗口函数3.表达式作为默认值:4.CHECK支持5.隐藏列-MySQL8.0.236.隐藏索引、降序索引、函数索引(MySQL-8.0.19)7.VALUES语法8.INTERSECT和EXC......
  • PLSQL重命名表的方法和报错解决方法ORA-01765 ORA-14047
    重命名办法在PLSQL中重命名表,在表上点右健选重命名。 报错ORA-01765若不是本用户,会报错:ORA-01765:不允许指定表的所有者名称。 解决方法,使用RENAME命令在PLSQL执行不会报错。示例:ALTERTABLEuser1.log_tablenameRENAMETOlog_tablename_back20240131; 报错ORA-14047......
  • mysql导入数据的问题
    简介:在我们使用高版本mysql的时候,比如mysql8,到mysql5.7恢复就报错,比如下面这样的错误:在我们使用高版本mysql的时候,比如mysql8,到mysql5.7恢复就报错,比如下面这样的错误:[Err]1273-Unknowncollation:'utf8mb4_0900_ai_ci'这就是字符集编码的问题,但是我将数据库的编码改成了......