#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;