Как обновить несколько значений в oracle?

#oracle #sql-update

Вопрос:

У меня есть два стола:

 table 1:
|Project type|Quarter1|Quarter2|Quarter3|Quarter4|
|------------|--------|--------|--------|--------|
|type1       |1       |3       |5       |7       |
|type2       |2       |4       |6       |8       |

table 2:
|Project|Value|Quarter|
|-------|-----|-------|
|type1  |     |1      |
|type2  |     |1      |
|type1  |     |2      |
|type2  |     |2      |
|type1  |     |3      |
|type2  |     |3      |
|type1  |     |4      |
|type2  |     |4      |
 

Я хочу обновить раздел значений таблицы 2 данными из таблицы 1, и ожидаемый результат будет:

 |Project|Value|Quarter|
|-------|-----|-------|
|type1  |1    |1      |
|type2  |2    |1      |
|type1  |3    |2      |
|type2  |4    |2      |
|type1  |5    |3      |
|type2  |6    |3      |
|type1  |7    |4      |
|type2  |8    |4      |
 

Я знаю, что обновление одного значения может быть записано как:

 update table2 a 
   set a.value = (select Quarter1 
                    from table1
                   where projecttype = 'type1')
 where a.project = 'type1'
   and a.quarter = '1';
 

Пожалуйста, скажите мне, как я могу обновить все значения за один раз?

Спасибо!

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

1. Почему «цикл для»? Все это может быть сделано в одной инструкции SQL; в SQL нет циклов «для».

2. Пока вы не научитесь форматировать код, пожалуйста, не редактируйте его снова. (Это просто: выберите код, а затем используйте кнопку {} форматирования в меню форматирования.) Я отредактировал, чтобы удалить все ссылки на «циклы» — в SQL нет «циклов» любого рода («для цикла» или любого другого). Кроме того, «результат» был правильным; «вывод» — это то, что вы получаете из SELECT запроса, а не из обновления таблицы.

Ответ №1:

Один из способов merge -это утверждение:

 merge into table_2 t
  using    table_1 s
     on    (t.project = s.project_type)
when matched then update
  set t.value = case t.quarter when 1 then s.quarter1
                               when 2 then s.quarter2
                               when 3 then s.quarter3
                               when 4 then s.quarter4 end
;
 

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

1. Спасибо, сэр! Я впервые задаю вопрос на этом сайте. Я пытаюсь привыкнуть к этому. Еще раз спасибо, что проинструктировали меня как по кодированию, так и по форматированию.

Ответ №2:

Это моя основная мысль об использовании цикла для повторения процесса обновления. Основная часть относится к ответу mathguy (еще раз спасибо). Это может усложнить код в этом сценарии, но было бы полезно, если в таблице 1 имеется множество столбцов, таких как годы вместо кварталов.

 declare
  
  quart_num number;
  code      varchar2(2000);
begin

  for quart_num in 1..4
  loop
      code := 'merge into table2 a
               using table1 b
               on (a.project = b.projecttype)
               when matched then
               update set a.value = quarter'||
               quart_num || 'where a.quarter =' ||quart_num;
      execute immediate(code);
   end loop;
end;