SQL 强大的关键字 Merge

本贴最后更新于 2959 天前,其中的信息可能已经事过境迁

介绍

 
        Merge 关键字是一个神奇的 DML 关键字。它在 SQL Server 2008 被引入,它能将 Insert,Update,Delete 简单的并为一句。MSDN 对于 Merge 的解释非常的短小精悍:”根据与源表联接的结果,对目标表执行插入、更新或删除操作。例如,根据在另一个表中找到的差异在一个表中插入、更新或删除行,可以对两个表进行同步。”,通过这个描述,我们可以看出 Merge 是关于对于两个表之间的数据进行操作的。可以想象出,需要使用 Merge 的场景比如:

  • 数据同步
  • 数据转换
  • 基于源表对目标表做 Insert,Update,Delete 操作

语法

merge [into] [目标表]
using <源表>
on 条件
when matched 操作 
when not matched 操作;

举个例子

        Merge 建立连个表 t1,t2。

CREATE TABLE t1 (
    id INT PRIMARY KEY,
    name VARCHAR(20),
    department VARCHAR(20),
    grade INT DEFAULT 0
);
CREATE TABLE t2 (
    id INT PRIMARY KEY,
    name VARCHAR(20),
    department VARCHAR(20),
    grade INT DEFAULT 0
);

        Merge 插入测试数据

INSERT  INTO dbo.t1
    ( id, name, department, grade )
    VALUES  ( 1, 'aaaa', 'd1', 60 ),
    ( 2, 'bbbb', 'd2', 70 ),
    ( 3, 'cccc', 'd2', 70 ),
    ( 4, 'dddd', 'd2', 70 ),
    ( 5, 'eeee', 'd2', 75 ),
    ( 6, 'ffff', 'd2', 70 ),
    ( 7, 'gggg', 'd2', 80 );
INSERT  INTO dbo.t2
    ( id, name, department, grade )
VALUES  ( 1, 'aaaa', 'd1', 60 ),
    ( 2, 'bbbb', 'd2', 70 ),
    ( 3, 'cccc', 'd3', 74 ),
    ( 4, 'dddd', 'd4', 77 ),
    ( 5, 'eeee', 'd5', 75 ),
    ( 6, 'ffff', 'd6', 70 ),
    ( 7, 'gggg', 'd7', 88 ),
    ( 8, 'hhhh', 'd8', 70 ),
    ( 9, 'iiii', 'd7', 70 ),
    ( 10, 'jjjj', 'd9', 70 ),
    ( 11, 'kkkk', 'd9', 70 );

        用 merge 语句将 t2 表的数据更新到 t1 表,如果 t1 表里存在 t2 表有 name 字段相等的数据(当然匹配条件可以有多个),就用 t2 表的 department 字段值更新 t1 表的 department 值,如果 t2 表的 name 字段值在 t1 表里不存在就在 t1 表里插入新的行。

MERGE INTO dbo.t1
USING dbo.t2
ON dbo.t1.name = t2.name --匹配字段
WHEN MATCHED THEN UPDATE SET t1.department = t2.department --匹配有就更新
WHEN NOT MATCHED THEN INSERT VALUES(id,name,department,grade); --匹配没有就插入

        Merge 当然如果看不出都对 t1 表做了哪些操作,还可以借助 OUTPUT 关键字来查看变化,例如修改语句如下

MERGE INTO dbo.t1
USING dbo.t2
ON dbo.t1.name = t2.name
WHEN MATCHED THEN UPDATE SET t1.department = t2.department
WHEN NOT MATCHED THEN INSERT VALUES(id,name,department,grade)
OUTPUT --显示操作变化
$action AS 操作类型,
Inserted.id AS 插入id,
Inserted.name AS 插入name,
Inserted.department AS 插入department,
Inserted.grade AS 插入grade;

        Merge 执行结果如图

  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    330 引用 • 614 回帖 • 3 关注
  • SQL
    124 引用 • 296 回帖 • 3 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...