Синтаксис оператора Merge
Merge относится к DML (Data Manipulation Language) языка SQL. Оператор появился с версии SQL Server 2008 и используется для того, чтобы привести 2 набора данных в соответствие — добавить строки, если их нет, обновить, если строки найдены, и удалить (опционально).
Merge можно использовать не только для того, чтобы сделать вставку или изменение данных, но с точки зрения производительности выгоднее будет вызывать классические Insert или Update.
Сразу хочу сказать, что синтаксис приводится в упрощённом варианте, чтобы сначала изучить базовую функциональность, а потом уже погружаться глубже.
MERGE <target_table> [AS TARGET] USING <table_source> [AS SOURCE] ON <search_condition> [WHEN MATCHED THEN <merge_matched> ] [WHEN NOT MATCHED [BY TARGET] THEN <merge_not_matched> ] [WHEN NOT MATCHED BY SOURCE THEN <merge_matched> ] [OUTPUT];
Разберём каждую часть
Target table — целевая таблица, именно в ней данные будут добавлены, изменены или удалены в результате выполнения оператора.
Source table — исходная таблица или таблица-источник данных, с которой будет сравниваться целевая таблица, это может быть любой набор данных. Предложение USING напоминает предложение FROM из оператора SELECT, тут можно указать таблицу, подзапрос, табличное выражение или функцию, возвращающую таблицу.
Далее ON — условие соединения двух таблиц (а точнее, наборов данных), такое же как ON в JOIN.
Теперь посмотрим на соотношение
Следующие 3 части оператора
When Matched — описывает действие, которое срабатывает для строк, которые нашлись и в Source, и в Target по условию, которое описано в ON. В этой части чаще всего встречается оператор UPDATE, хотя возможно использование оператора DELETE.
When Not Matched [By Target] — описывает действие для строк, которые есть в таблице Source, но отсутствуют в таблице Target; далее используется оператор INSERT, и указанные строки добавляются в таблицу Target.
When Not Matched By Source — описывает действие для строк, которые отсутствуют в таблице Source, но найдены в таблице Target, чаще всего встречается оператор DELETE, чтобы удалить строки и привести 2 набора в соответствие, но возможно использование оператора Update.
Если переложить на оператор, то получится:
Например, возьмём загрузку данных о наличие книг:
Строки 1 и 2 — произойдёт Update, строки 3 и 4 — Insert, а строка 5 — из таблицы Target будет удалена Delete.
И последняя часть оператора в примере
OUTPUT — отличается тем, что есть специальная функция
Ниже пример кода с Merge:
CREATE TABLE BooksSalesStat (BookId BIGINT PRIMARY KEY, BookName VARCHAR(128), SalesCount INT); CREATE TABLE StagingBooksSalesStat (BookId BIGINT PRIMARY KEY, BookName VARCHAR(128), SalesCount INT); INSERT INTO BooksSalesStat (BookId, BookName, SalesCount) VALUES (1,'Остров Сокровищ', 4), (2,'Незнайка', 5), (5,'Алые паруса', 2); INSERT INTO StagingBooksSalesStat (BookId, BookName, SalesCount) VALUES (1,'Остров Сокровищ', 4), (2,'Незнайка', 5), (3,'Робинзон Крузо', 10), (4,'Руслан и Людмила', 12); MERGE BooksSalesStat AS Target USING StagingBooksSalesStat AS Source ON (Target.BookId = Source.BookId) WHEN MATCHED THEN UPDATE SET SalesCount = Source.SalesCount WHEN NOT MATCHED THEN INSERT VALUES (Source.BookId, Source.BookName, Source.SalesCount) WHEN NOT MATCHED BY SOURCE THEN DELETE OUTPUT deleted.*, $action, inserted.*;
Что можно почитать по Merge: 1. Ben-Gan I., Sarka D., Talmage R. — Training Kit (Exam 70-461) Querying Microsoft SQL Server 2012-2012, Глава 11. 2. Документация. 3. Статья.
Есть вопрос? Напишите в комментариях!