Как обновить несколько записей с помощью инструкции MERGE и использовать max(column_value) на основе ранее обновленных записей в той же инструкции?

Мне нужно использовать оператор Oracle MERGE для обновления записей таблицы. Один из столбцов, который я хотел бы обновить, должен быть получен из значения MAX как существующих записей таблицы, так и записей, которые обновляются как часть текущего оператора MERGE. Как мне это сделать?

при обновлении я попробовал max (значение столбца) в качестве внутреннего запроса, но он не учитывал записи, которые обновляются как часть MERGE.

Ниже представлена ​​примерная таблица.

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

ИМЯ ТАБЛИЦЫ: Структура

PARENT     CHILD    OCCURRENCE
A          M        1
A          M        2
A          F        1
B          M        1

Обратите внимание, что я упомянул только несколько столбцов и записей этой таблицы, чтобы объяснить требование. Я хотел бы обновить родительский элемент «A» до «B». При обновлении трех записей я должен соответствующим образом обновить вхождение. Ниже приведен оператор MERGE, который я пробовал.

MERGE INTO STRUCTURE a
USING (                                            
      select 'A' as old_parent,
             'B' as new_parent,
             child as child from STRUCTURE
  ) b ON (a.parent = b.old_parent)                                              
  WHEN MATCHED THEN
      UPDATE SET parent = b.new_parent,
                 occurrence = (SELECT NVL(MAX(occurrence)) + 1 
                                  FROM structure
                                  WHERE parent = b.new_parent and
                                  child = b.child)

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

Ниже ожидаемый результат

PARENT     CHILD    OCCURRENCE
B          M        2
B          M        3
B          F        1
B          M        1

Фактический результат, который я получил


PARENT     CHILD    OCCURRENCE
B          M        2
B          M        2
B          F        1
B          M        1

Буду признателен за любую помощь/рекомендации о том, как мне добиться этого в одном выражении MERGE. Если это невозможно, есть ли другой способ сделать это с помощью одного оператора в SQL? Спасибо.


person Raghu    schedule 09.08.2019    source источник


Ответы (1)


РЕДАКТИРОВАТЬ 3: Я успешно получил результат вашего желания, но не понимаю, зачем вам такой результат. Пожалуйста, измените предложение from и поместите его в свой слияние:

SELECT parent old_parent,
       'B'    AS new_parent,
       child  AS child,
       occurence,
         MAX (occurence) OVER (PARTITION BY parent, CHILD ORDER BY 1)
       + COUNT (*) OVER (PARTITION BY parent, child ORDER BY 1)
       - OCCURENCE
           NEW_OCCURENCE
  FROM (SELECT 'a' parent, 'm' child, 1 occurence FROM DUAL
        UNION ALL
        SELECT 'a' parent, 'm' child, 2 occurence FROM DUAL
        UNION ALL
        SELECT 'a' parent, 'f' child, 1 occurence FROM DUAL
        UNION ALL
        SELECT 'b' parent, 'm' child, 1 occurence FROM DUAL) STRUCTURE

результат

Я думаю, что вы можете использовать Макс как аналитическую функцию. См. слияние ниже:

MERGE INTO STRUCTURE a
     USING (SELECT old_parent,
                   'B'   AS new_parent,
                   child AS child,
                   MAX (occurrence) OVER (PARTITION BY old_parent, CHILD ORDER BY 1) + 1
                       NEW_OCCURENCE
              FROM STRUCTURE) b
        ON (a.parent = b.old_parent)
WHEN MATCHED
THEN
    UPDATE SET parent = b.new_parent, occurrence = b.NEW_OCCURENCE;
person F.Lazarescu    schedule 09.08.2019
comment
Я попробую, но не могли бы вы сказать, будет ли он учитывать не только записи, которые уже присутствуют в таблице, но также записи, которые обновляются как часть этого MERGE, и соответственно предоставит следующее вхождение? Я сомневаюсь. - person Raghu; 09.08.2019
comment
Привет, да, вы правы: не учитываются записи, которые будут обновлены в рамках этого слияния. Я не понимаю, зачем вам это нужно.. как изменится результат, если мы сможем это сделать.. - person F.Lazarescu; 09.08.2019
comment
Пожалуйста, проверьте ожидаемую и фактическую таблицу, приведенную выше. С моим SQL и вашим SQL вторая запись не будет обновлена ​​​​на 3 как появление. - person Raghu; 09.08.2019
comment
@Raghu, я только что изменил свой ответ, пожалуйста, посмотри сейчас. Он возвращает желаемый результат. - person F.Lazarescu; 09.08.2019
comment
Но какая часть вашего SQL рассматривает записи, которые мы обновляем, как часть MERGE? Если я прав, упомянутая вами часть SELECT будет выполняться только один раз в начале, и обновление будет происходить на основе количества записей, которые дает SELECT, поэтому мы всегда получаем «2». Поправьте меня, если я ошибаюсь. - person Raghu; 09.08.2019
comment
Только что заметил ваше обновление, я попробую и сообщу вам в понедельник, так как я путешествую и не имею доступа к работе. Спасибо за ваши усилия. - person Raghu; 09.08.2019
comment
Ваше предположение частично верно. Почему 2? у тебя там 4 ряда.. у меня голова кружится :) - person F.Lazarescu; 09.08.2019
comment
Я хотел бы обновить только записи, чьим родителем является «A», до «B». Не закружитесь. Это просто требование бизнеса :) - person Raghu; 09.08.2019
comment
Так что я думаю, что просто, где parent = A, выберет только 3 записи из 4. Это правильно? - person F.Lazarescu; 09.08.2019
comment
Не требование бизнеса, а ситуация. Приложение, над которым я сейчас работаю, имеет несколько довольно старых таблиц с родительскими, дочерними столбцами и столбцами вхождения, которые все вместе определены как уникальные. Мы не можем изменить ограничение. Следовательно, нам нужно обновить вхождение на основе комбинации родительского и дочернего элементов, чтобы они оставались уникальными. - person Raghu; 09.08.2019
comment
Да, 3 записи необходимо обновить с помощью «B» в качестве родителя, и следует соблюдать осторожность, как указано выше. - person Raghu; 09.08.2019
comment
Использование MERGE является бизнес-требованием? - person Popeye; 10.08.2019
comment
Спасибо, Лазареску!. Это помогло моему сценарию. - person Raghu; 12.08.2019