В этом руководстве вы узнаете, как использовать оператор MERGE SQL Server для обновления данных в таблице на основе значений, сопоставленных с другой таблицей.
Введение SQL Server MERGE Statement
Предположим, у вас есть две таблицы, называемые исходной и целевой, и вам нужно обновить целевую таблицу на основе значений, сопоставленных с исходной таблицей. Есть три случая:
- В исходной таблице есть некоторые строки, которых нет в целевой таблице. В этом случае вам нужно вставить строки, которые есть в исходной таблице, в целевую таблицу.
- В целевой таблице есть некоторые строки, которых нет в исходной таблице. В этом случае вам нужно удалить строки из целевой таблицы.
- В исходной таблице есть несколько строк с теми же ключами, что и в строках целевой таблицы. Однако эти строки имеют разные значения в неключевых столбцах. В этом случае вам необходимо обновить строки в целевой таблице значениями из исходной таблицы.
На следующем рисунке показаны исходная и целевая таблицы с соответствующими действиями: вставка, обновление и удаление:

Если вы используете операторы 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 определяет, как строки из исходной таблицы сопоставляются со строками из целевой таблицы. Это похоже на условие соединения в предложении соединения. Обычно для сопоставления используются ключевые столбцы — первичный ключ или уникальный ключ.
В-третьих, merge_condition приводит к трем состояниям: СООТВЕТСТВУЕТ, НЕ СООТВЕТСТВУЕТ и НЕ СООТВЕТСТВУЕТ ПО ИСТОЧНИКУ.
- MATCHED: это строки, которые соответствуют условию слияния. На диаграмме они показаны синим цветом. Для соответствующих строк вам необходимо обновить столбцы строк в целевой таблице значениями из исходной таблицы.
- NOT MATCHED: это строки из исходной таблицы, которые не имеют соответствующих строк в целевой таблице. На диаграмме они показаны оранжевым цветом. В этом случае вам необходимо добавить строки из исходной таблицы в целевую таблицу. Обратите внимание, что NOT MATCHED также известно как NOT MATCHED BY TARGET.
- НЕ СООТВЕТСТВУЮТ ИСТОЧНИКУ: это строки в целевой таблице, которые не соответствуют ни одной строке в исходной таблице. Они показаны зеленым на диаграмме. Если вы хотите синхронизировать целевую таблицу с данными из исходной таблицы, вам нужно будет использовать это условие соответствия для удаления строк из целевой таблицы.
Пример оператора MERGE SQL Server
Предположим, у нас есть две таблицы 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(целевая таблица) значениями из 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;

В этом примере мы использовали значения в столбцах category_id в обеих таблицах в качестве условия слияния.
- Во-первых, строки с идентификаторами 1, 3, 4 из таблицы sales.category_staging совпадают со строками из целевой таблицы, поэтому оператор MERGE обновляет значения в столбцах «Название категории» и «Количество» в таблице sales.category.
- Во-вторых, строки с идентификаторами 5 и 6 из таблицы sales.category_staging отсутствуют в таблице sales.category, поэтому оператор MERGE вставляет эти строки в целевую таблицу.
- В-третьих, строка с идентификатором 2 из таблицы sales.category не существует в таблице sales.sales_staging, поэтому оператор MERGE удаляет эту строку.
В результате слияния данные в таблице sales.category полностью синхронизированы с данными в таблице sales.category_staging.
В этом руководстве вы узнали, как использовать оператор SQL Server MERGE для внесения изменений в таблицу на основе совпадающих значений из другой таблицы.




