Применение оператора MERGE в PostgreSQL

Оператор MERGE — это мощный инструмент, который можно использовать для выполнения условных операций INSERT, UPDATE или DELETE строк в таблице. Он был введен в стандарте SQL:2003 и расширен в стандарте SQL:2008.

В этой статье мы рассмотрим, как использовать оператор MERGE в PostgreSQL для эффективного выполнения этих операций.

MERGE похож на оператор UPSERT в других диалектах SQL, но имеет ряд преимуществ, включая:

  • Он более эффективен, поскольку выполняет только необходимые операции для каждой строки.
  • Он атомарный, поскольку либо успешно выполняется, либо завершается неудачей целиком.
  • Он более гибкий, поскольку позволяет указывать более сложные условия.

В PostgreSQL до версии 15 для условных операций INSERT, UPDATE и DELETE можно было использовать оператор INSERT INTO ... ON CONFLICT [ conflict_target ] conflict_action. Однако, начиная с версии 15, появилась возможность использовать все преимущества оператора MERGE.

Синтаксис оператора MERGE выглядит следующим образом:

MERGE INTO target_table AS t USING source_table AS s ON WHEN MATCHED THEN WHEN NOT MATCHED THEN

Здесь target_table — это таблица, которую нужно обновить или в которую нужно вставить строки.

source_table — это таблица, содержащая данные, которые будут использоваться для обновления или вставки строк в target_table.

Условие — это логическое выражение, используемое для определения, нужно ли обновлять или вставлять строку из source_table.

update_statement — это SQL-запрос, используемый для обновления строк в target_table.

insert_statement — это SQL-запрос, используемый для вставки строк в target_table.

Вот пример оператора MERGE, который обновляет таблицу customers, используя таблицу leads. Обе таблицы имеют поле email, поэтому нам нужно добавлять только те строки из leads, email которых не существует в таблице customers:

MERGE INTO customers AS c USING leads AS l ON c.email = l.email WHEN NOT MATCHED THEN insert (name, email, created_at) VALUES (l.name, l.email, DEFAULT);

Для каждой строки, для которой не нет соответствия, будет выполнен запрос на вставку. 

Этот запрос эквивалентен следующему запросу UPSERT:

INSERT INTO customers (name, email) SELECT name, email FROM leads ON conflict (email) DO nothing;

Но, если мы посмотрим на результаты, мы увидим преимущество оператора MERGE: он не увеличивает поле id в случае, если запись уже существует. Здесь можно выполнить тест SQL.

Давайте попробуем выполнить более сложную задачу. Теперь мы добавим новые записи в таблицу customers с новыми электронными адресами и обновим имя для уже существующих записей.

MERGE INTO customers AS c USING leads AS l ON c.email = l.email WHEN NOT MATCHED THEN INSERT (name, email, created_at) VALUES (l.name, l.email, DEFAULT) WHEN MATCHED THEN UPDATE SET name = l.name ;

А в последнем сценарии мы добавим записи в таблицу customers с отсутствующими электронными адресами, обновим имя, если дата создания клиента меньше, чем соответствующая дата в leads, и удалим другие записи:

MERGE INTO customers AS c USING leads AS l ON c.email = l.email WHEN NOT MATCHED THEN INSERT (name, email, created_at) VALUES (l.email, l.name, DEFAULT) WHEN MATCHED AND c.created_at < l.created_at THEN UPDATE SET name = l.name WHEN MATCHED THEN DELETE ;

Таким образом мы познакомились с командой MERGE, которая позволяет выполнять условные операции INSERT, UPDATE или DELETE на строках таблицы. Этот инструмент более эффективен, атомарен и гибок, чем другие SQL-диалекты.

Благодаря MERGE можно выполнять более сложные задачи, связанные с обновлением и вставкой данных в таблицы.

Следите за новыми постами по любимым темам

Подпишитесь на интересующие вас теги, чтобы следить за новыми постами и быть в курсе событий.

    Данные о правообладателе фото и видеоматериалов взяты с сайта «Tproger», подробнее в Условиях использования