在本教程中,将学习如何使用SQL Server MERGE
语句根据与另一个表匹配的值更新表中的数据。
SQL Server MERGE语句简介
假设有两个表名为:source
表和target
表,并且需要根据source
表中匹配的值更新target
表。 有三种情况:
source
表有一些target
表中不存在的行。在这种情况下,需要将source
表中的行插入到target
表中。target
表有一些source
表中不存在的行。 在这种情况下,需要从target
表中删除行。source
表的某些行具有与target
表中的行相同的键。 但是,这些行在非键列中具有不同的值。 在这种情况下,需要使用来自source
表的值更新target
表中的行。
下图说明了source
表和target
表以及相应的操作:插入,更新和删除:
如果单独使用INSERT
,UPDATE
和DELETE
语句,则必须构造三个单独的语句,以使用source
表中的匹配行将数据更新到target
表。
但是,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
子句中指定source_table
表和target_table
表。
其次,merge_condition
确定source_table
表中的行如何与target_table
表中的行匹配。 它类似于join
子句中的join
条件。 通常,使用主键或唯一键的键列进行匹配。
第三,merge_condition
有三种状态:MATCHED
,NOT MATCHED
和NOT MATCHED BY SOURCE
。
MATCHED
:这些是与合并条件匹配的行。 在图中,它们显示为蓝色。 对于匹配的行,需要使用source_table
表中的值更新target_table
表中的行列。NOT MATCHED
:这些是source_table
表中的行,target_table
表中没有任何匹配的行。 在图中,它们显示为橙色。 在这种情况下,需要将source_table
表中的行添加到target_table
表。 请注意,NOT MATCHED BY TARGET
也称为目标不匹配。NO MATCHED BY SOURCE
:这些是target_table
表中与source_table
表中的任何行都不匹配的行。 它们在图中显示为绿色。 如果要将target_table
表与source_table
表中的数据同步,则需要使用此匹配条件从target_table
表中删除行。
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,'Children Bicycles',15000),
(2,'Comfort Bicycles',25000),
(3,'Cruisers Bicycles',13000),
(4,'Cyclocross Bicycles',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,'Children Bicycles',15000),
(3,'Cruisers Bicycles',13000),
(4,'Cyclocross Bicycles',20000),
(5,'Electric Bikes',10000),
(6,'Mountain Bikes',10000);
要使用sales.category_staging
(源表)中的值将数据更新到sales.category
(目标表),请使用以下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;
执行过程如下图所示 -
在此示例中,使用两个表中category_id
列中的值作为合并条件。
- 首先,
sales.category_staging
表中id
值为1
,3
,4
的行与目标表中的行匹配,因此,MERGE
语句更新sales.category
表中类别名称和amount
列中的值。 - 其次,
sales.category_staging
表中id
值为5
和6
的行在sales.category
表中不存在,因此MERGE
语句将这些行插入到目标表中。 - 第三,
sales.sales_staging
表中不存在sales.category
表中具有id
值为2
的行,因此,MERGE
语句将删除此行。
在合并的结果中,sales.category
表中的数据与sales.category_staging
表中的数据完全同步。
在本教程中,学习了如何使用SQL Server MERGE语句根据来自另一个表的匹配值在表中进行更改。