Как понять ключевое слово MERGE с SQL Server 2008

#sql-server-2008 #merge

#sql-server-2008 #объединить

Вопрос:

У меня есть базовое понимание синтаксиса MERGE для SQL Sever 2008, но у меня есть вопрос о расширенном использовании концепции.

Представьте, что у меня есть спортивная команда, в которой 30 игроков. Каждый проигрыватель представляет собой запись в таблице. Сейчас, в середине сезона, некоторые игроки ушли (травма, что угодно), и им на замену прибыла новая команда.

Итак, я хочу обновить таблицу базы данных, чтобы точно отразить это изменение.

Итак, когда я использую MERGE синтаксис, если новый проигрыватель не существует, он вставляется:

 WHEN NOT MATCHED THEN
    INSERT blah blah blah...
    VALUES (blah blah and more blah)..
  

и когда оно совпадает, тогда ничего не делайте (поэтому мне не нужно иметь никакого WHEN MATCHED THEN предложения).

Но как насчет тех игроков, которые ушли? Здесь WHEN NOT MATCHED BY SOURCE THEN <merge_matched> вступает в игру?

Если да, то как мне следует его использовать?

Ответ №1:

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

Сезон начинается с этой командой

 PlayerName           Position
-------------------- --------
Brett Favre          QB
Joe Montana          QB
John Elway           QB
  

В середине сезона тренер понимает, что не оптимально иметь команду с тремя довольно старыми QB. Бретт отказывается увольняться, поэтому Джо должен уйти. Джон начинает играть в RB, и в то же время нам нужны молодые люди, чтобы наладить работу.

 PlayerName           Position
-------------------- --------
Brett Favre          QB
John Elway           RB
Jerry Rice           WR
Karl Mecklenburg     LB
  

Инструкция merge для слияния NewTeam с Team будет выглядеть следующим образом.

 merge Team as T
using NewTeam as S
on S.PlayerName = T.PlayerName
when matched then
  update set Position = S.Position
when not matched by target then
  insert (PlayerName, Position) values (S.PlayerName, S.Position)
when not matched by source then
  delete;  
  

Комментарии:

1. Идеальное объяснение 🙂 Я попробую это сделать 🙂

Ответ №2:

Да, WHEN NOT MATCHED BY SOURCE THEN <merge_matched> это раздел, в котором вы можете позаботиться об ушедших игроках.

Согласно документу, вы можете использовать ОБНОВЛЕНИЕ (например, установить Active атрибут на 0 ) или инструкцию по УДАЛЕНИЮ там.

Из документации вы можете узнать, что таких разделов может быть два. В этом случае один из них определен с дополнительным условием и может принимать только инструкцию UPDATE:

 WHEN NOT MATCHED BY SOURCE AND condition THEN
    UPDATE SET ...  

Другое не должно использовать условие и зарезервировано для инструкции УДАЛЕНИЯ.