Oracle PL/SQL: обновить таблицу B с помощью агрегированных данных таблицы A

Предположим, у вас есть таблица Oracle, TABLE A, как показано ниже:

введите здесь описание изображения

В этой таблице основными полями являются FIELD1 и FIELD2. Ты это видишь:

а) Для пары (ААА, 1) имеем два значения: 200,03 и 100,02; б) Для пары (ВВВ, 3) имеем два значения: 300,04 и 400,05.

Мы хотели бы сделать агрегацию суммы следующим образом, обновив следующую таблицу:

введите здесь описание изображения

В поле 3 таблицы B мы хотели бы сохранить сумму 200,03 и 100,02 по отношению к паре (AAA, 1), и мы хотели бы сохранить сумму 300,04 и 400,05 по отношению к паре (BBB, 3) .

Пожалуйста, представьте, что у нас может быть много разных пар: (ZZZ, 77) (YYY, 12) ... и так далее.

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

В нашем простом случае результат будет следующим:

введите здесь описание изображения

В реальном случае есть таблица A с примерно 20 миллионами записей, поэтому я хотел бы написать программное обеспечение на PL/SQL, используя BULK COLLECT, UPDATE и FORALL.

Что было бы лучшим подходом? Предоставьте код PL/SQL, чтобы объяснить, как решить проблему.

Большое спасибо за рассмотрение моей просьбы.


person UltraCommit    schedule 23.11.2015    source источник


Ответы (1)


Честно говоря, я бы не стал использовать здесь BULK COLLECT и FORALL — я бы использовал оператор MERGE. Попробуйте что-то вроде

MERGE INTO TABLE_B b
  USING (SELECT FIELD1, FIELD2, SUM(FIELD3) AS TOTAL_FIELD3
           FROM TABLE_A
           GROUP BY FIELD1, FIELD2) a
    ON (b.FIELD1 = a.FIELD1 AND
        b.FIELD2 = a.FIELD2)
WHEN NOT MATCHED THEN
   INSERT (FIELD1, FIELD2, FIELD3)
     VALUES (a.FIELD1, a.FIELD2, a.TOTAL_FIELD3)
WHEN MATCHED THEN
   UPDATE
     SET FIELD3 = a.TOTAL_FIELD3;

Удачи.

person Bob Jarvis - Reinstate Monica    schedule 23.11.2015
comment
удаляет-наполовину написанный-ответ-и-просто-проголосует-за-Боба - person David Aldridge; 23.11.2015
comment
Но читал в инете, что для ОГРОМНЫХ таблиц НЕ удобно ОБЪЕДИНЯТЬ.....! - person UltraCommit; 23.11.2015
comment
Я указал, что у нас есть двадцать миллионов записей, поэтому в ОДНОЙ ТРАНЗАКЦИИ невозможно обновить 20 миллионов записей....! По этой причине более удобен подход с BULK COLLECT, UPDATE и FORALL. - person UltraCommit; 23.11.2015
comment
Вам лучше выяснить, как разделить данные на достаточно небольшие группы, чтобы вы могли использовать MERGE, а не читать 20 миллионов строк данных в память PL/SQL, используя BULK COLLECT в коллекцию, а затем повторяя это, а огромная коллекция данных. Удачи. - person Bob Jarvis - Reinstate Monica; 24.11.2015
comment
Я намеревался BULK COLLECT с предложением LIMIT, конечно, чтобы избежать чтения 20 миллионов строк за одно и то же время. - person UltraCommit; 24.11.2015