#sql #oracle12c
#sql #oracle12c
Вопрос:
У меня есть таблица 1, подобная этой:
----- ----- ------
| cat | val | type |
----- ----- ------
| A | 100 | c1 |
| H | 25 | c2 |
| H | 50 | c3 |
| H | 30 | c2 |
| A | 15 | c3 |
| H | 10 | c1 |
| H | 15 | c1 |
| B | 10 | c4 |
| H | 20 | c4 |
| H | 15 | c3 |
----- ----- ------
Мне нужно добавить группу sum (val) по типу только к одному H, принадлежащему каждому типу
Итак, у меня есть после группировки по типу, скажем, table2 :
----- -----
| cat | val |
----- -----
| c1 | 125 |
| c2 | 55 |
| c3 | 80 |
| c4 | 30 |
----- -----
Мне нужно добавить 125 к любому из H значений с типом c1, 55 к любому из H значений с c2 и так далее..Если в c1 нет H, то он должен создать эту запись.
Итак, наконец, мы получаем:
----- ----- ------
| cat | val | type |
----- ----- ------
| A | 100 | c1 |
| H | 25 | c2 |
| H | 130 | c3 |
| H | 85 | c2 |
| A | 15 | c3 |
| H | 135 | c1 |
| H | 15 | c1 |
| B | 10 | c4 |
| H | 50 | c4 |
| H | 15 | c3 |
----- ----- ------
Как мне это сделать, не выполняя группировку table1 union table2 (с ‘H’ в качестве cat) по типу? Также у меня нет прав на обновление и я не могу использовать хранимые процедуры. Я также должен иметь в виду, что table1 является результатом запроса, включающего несколько внутренних объединений, которые я не хочу использовать снова и снова для операторов select.
Комментарии:
1. Почему строка
| H | 25 | c2 |
вообще не меняется? То же самое для| H | 15 | c1 |
и| H | 15 | c3 |
?2. @MatBailie потому что необходимо обновить любую комбинацию (H, Cs) и не более того
Ответ №1:
Посмотрите, имеет ли это смысл. Я добавил столбец ID просто для отображения конечного результата в том же порядке, что и входные данные (для облегчения чтения).
SQL> -- T1 is what you currently have; it can/could be your current query
SQL> with t1 (id, cat, val, type) as
2 (select 1, 'A', 100, 'C1' from dual union all
3 select 2, 'H', 25 , 'C2' from dual union all
4 select 3, 'H', 50 , 'C3' from dual union all
5 select 4, 'H', 30 , 'C2' from dual union all
6 select 5, 'A', 15 , 'C3' from dual union all
7 select 6, 'H', 10 , 'C1' from dual union all
8 select 7, 'H', 15 , 'C1' from dual union all
9 select 8, 'B', 10 , 'C4' from dual union all
10 select 9, 'H', 20 , 'C4' from dual union all
11 select 10,'H', 15 , 'C3' from dual
12 ),
13 -- sum VAL per type
14 t1_sum as
15 (select type, sum(val) sum_val
16 from t1
17 group by type
18 ),
19 -- find row number; let any H be number 1
20 t1_rn as
21 (select id, cat, val, type,
22 row_number() over (partition by type
23 order by case when cat = 'H' then 1 end) rn
24 from t1
25 )
26 -- the final resu< add SUM_VAL to the first H row per type
27 select r.cat, r.val case when r.rn = 1 then s.sum_val else 0 end val,
28 r.type
29 From t1_rn r join t1_sum s on s.type = r.type
30 order by r.id;
CAT VAL TYPE
--- ---------- ----
A 100 C1
H 80 C2
H 130 C3
H 30 C2
A 15 C3
H 135 C1
H 15 C1
B 10 C4
H 50 C4
H 15 C3
10 rows selected.
SQL>
[РЕДАКТИРОВАТЬ: пытаюсь прояснить, как использовать ваш большой запрос]
Предположим, что это ваш очень большой и сложный запрос:
select a.cat,
case when a.cat = 'A' then b.val
when a.cat = 'Z' then c.val
else 'H'
end val,
c.type
from a join b on a.id = b.id and a.x = b.y
join c on c.id = b.idx
where a.date_column < sysdate
and c.type = 'X';
Как я уже сказал, создайте представление на его основе в виде
create or replace view v_view as
select a.cat,
case when a.cat = 'A' then b.val
when a.cat = 'Z' then c.val
else 'H'
end val,
c.type
from a join b on a.id = b.id and a.x = b.y
join c on c.id = b.idx
where a.date_column < sysdate
and c.type = 'X';
и использовать его в качестве источника для «моего» запроса (начиная со строки 14 и далее):
with t1_sum as
(select type, sum(val) sum_val
from v_view --> here's the view
group by type
), etc.
Или используйте сам «огромный» запрос в качестве начального CTE:
with t1 as
-- this is your "huge" query
(select a.cat,
case when a.cat = 'A' then b.val
when a.cat = 'Z' then c.val
else 'H'
end val,
c.type
from a join b on a.id = b.id and a.x = b.y
join c on c.id = b.idx
where a.date_column < sysdate
and c.type = 'X'
),
-- sum VAL per type
t1_sum as
(select type, sum(val) sum_val
from t1
group by type
), etc.
Комментарии:
1. Но как это сделать, если количество записей в table1 очень велико? В реальном сценарии у меня было бы около 5 миллионов записей в таблице. Я, конечно, не могу выбрать использование ID индивидуально
2. А также я хочу использовать t1 только один раз, поскольку он имеет несколько внутренних объединений и множество операторов case, что делает запрос очень громоздким при использовании более одного раза.
3. Ваш «большой запрос с несколькими внутренними объединениями и множеством операторов case» был бы моим T1 CTE. Если вам неприятно это видеть, создайте представление на основе этого запроса. Кто что-нибудь говорил о выборе отдельных идентификаторов? Если вы имеете в виду столбец «мой идентификатор», то перечитайте еще раз, что я сказал об этом. Наконец, у меня нет никаких возражений, если вы напишете свой собственный код (или подождете немного дольше или неопределенно долго, пока кто-нибудь другой опубликует другой вариант). Вкратце: примите это или оставьте.
4. Безусловно, «возьму это» всего с несколькими разъяснениями -1. как мне написать инструкции «выберите 1, ‘A’, 100, ‘C1’ из двойного объединения all …» для всех строк, которые у меня есть в моей таблице, и 2. Если я использую сложное представление, смогу ли я выполнить дальнейшую группировку по нему? В любом случае спасибо, что приложили усилия для ответа
5. Я отредактировал свое сообщение и добавил еще немного кода, который, надеюсь, показывает, что я имел в виду. Взгляните, пожалуйста. Имеет ли это теперь больше смысла?