СЛИЯНИЕ SQL-сервера

В этом руководстве вы узнаете, как использовать оператор MERGE SQL Server для обновления данных в таблице на основе значений, сопоставленных с другой таблицей.

Введение SQL Server MERGE Statement

Предположим, у вас есть две таблицы, называемые исходной и целевой, и вам нужно обновить целевую таблицу на основе значений, сопоставленных с исходной таблицей. Есть три случая:

  1. В исходной таблице есть некоторые строки, которых нет в целевой таблице. В этом случае вам нужно вставить строки, которые есть в исходной таблице, в целевую таблицу.
  2. В целевой таблице есть некоторые строки, которых нет в исходной таблице. В этом случае вам нужно удалить строки из целевой таблицы.
  3. В исходной таблице есть несколько строк с теми же ключами, что и в строках целевой таблицы. Однако эти строки имеют разные значения в неключевых столбцах. В этом случае вам необходимо обновить строки в целевой таблице значениями из исходной таблицы.

На следующем рисунке показаны исходная и целевая таблицы с соответствующими действиями: вставка, обновление и удаление:

СЛИЯНИЕ SQL-сервера

Если вы используете операторы 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;

Пример MERGE для SQL Server

В этом примере мы использовали значения в столбцах 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 для внесения изменений в таблицу на основе совпадающих значений из другой таблицы.

Мирослав С.

Автор статей, ИБ-специалист