Сумма Oracle SQL по разделам при группировании по

#sql #oracle

Вопрос:

У меня есть таблица ниже:

OP vt вк gp БЫТЬ AU
OP1 ВТ1 ВК1 GP1 1 8
OP2 ВТ1 ВК1 GP1 2
OP3 ВТ2 ВК1 GP1 3 8
OP4 ВТ2 ВК1 GP1 4
OP5 ВТ3 ВК2 GP1 5 8
ОП6 ВТ3 ВК2 GP1 6
OP7 ВТ4 ВК2 GP1 7 8
OP8 ВТ4 ВК2 GP1 8
OP9 VT5 ВК3 GP2 9 8
ОП10 VT5 ВК3 GP2 10
ОП11 ВТ6 ВК3 GP2 11 8
OP12 ВТ6 ВК3 GP2 12
OP13 ВТ7 ВК4 GP2 13 8
ОП14 ВТ7 ВК4 GP2 14
ОП15 ВТ8 ВК4 GP2 15 8
ОП16 ВТ8 ВК4 GP2 16

И я хотел бы получить вывод ниже

vt вк gp VT_AU VT_AU8 VK_AU VK_AU8 GP_AU GP_AU8
ВТ1 ВК1 GP1 3 1 10 4 36 16
ВТ2 ВК1 GP1 7 3 10 4 36 16
ВТ3 ВК2 GP1 11 5 26 12 36 16
ВТ4 ВК2 GP1 15 7 26 12 36 16
VT5 ВК3 GP2 19 9 42 20 100 48
ВТ6 ВК3 GP2 23 11 42 20 100 48
ВТ7 ВК4 GP2 27 13 58 28 100 48
ВТ8 ВК4 GP2 31 15 58 28 100 48

До сих пор я пробовал это, но дополнительные разделы не могут работать с группой.

 -- Logic to obtain the output:
--VT_AU -> grouping by VT, sum of BE
--VT_AU8 -> grouping by VT, sum of BE when AU=8
--VK_AU -> grouping by VK, sum of BE
--VK_AU8 -> grouping by VK, sum of BE when AU=8
--GP_AU -> grouping by GP, sum of BE
--GP_AU8 -> grouping by GP, sum of BE when AU=8

with
  aux (op,vt, vk, gp, be, au) as (
    select 'OP1', 'VT1', 'VK1', 'GP1' , 1, 8 from dual union all
    select 'OP2', 'VT1', 'VK1', 'GP1', 2, null from dual union all
    select 'OP3', 'VT2', 'VK1' , 'GP1', 3, 8 from dual union all
    select 'OP4', 'VT2', 'VK1', 'GP1' , 4, null from dual union all
    select 'OP5', 'VT3', 'VK2' , 'GP1', 5, 8 from dual union all
    select 'OP6', 'VT3', 'VK2', 'GP1', 6, null from dual union all
    select 'OP7', 'VT4', 'VK2', 'GP1' , 7, 8 from dual union all
    select 'OP8', 'VT4', 'VK2', 'GP1', 8, null from dual union all
    select 'OP9', 'VT5', 'VK3' , 'GP2', 9, 8 from dual union all
    select 'OP10', 'VT5', 'VK3', 'GP2' , 10, null from dual union all
    select 'OP11', 'VT6', 'VK3' , 'GP2', 11, 8 from dual union all
    select 'OP12', 'VT6', 'VK3', 'GP2', 12, null from dual union all
    select 'OP13', 'VT7', 'VK4', 'GP2' , 13, 8 from dual union all
    select 'OP14', 'VT7', 'VK4', 'GP2', 14, null from dual union all
    select 'OP15', 'VT8', 'VK4' , 'GP2', 15, 8 from dual union all
    select 'OP16', 'VT8', 'VK4', 'GP2' , 16, null from dual
  )

SELECT
    vt,
    vk,
    gp,
    SUM(be) vt_au,
    sum(case when au=8 then be end) vt_au8,
    sum(be) over(partition by vk) vk_au,
    sum(case when au=8 then be end) over(partition by vk) vt_au8,
    sum(be) over(partition by gp) gp_au,
    sum(case when au=8 then be end) over(partition by gp) gp_au8
FROM
    aux
GROUP BY
    vt,
    vk,
    gp
ORDER BY
    vt,
    vk,
    gp;
 

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

1. Пожалуйста, объясните логику для столбцов. Не заставляй людей гадать.

2. Приносим извинения, пожалуйста, найдите мой вопрос отредактированным выше.

Ответ №1:

Если я правильно понимаю, вам нужна условная агрегация с оконными функциями:

 select VT, VK, GP,
       sum(be),
       sum(sum(case when au = 8 then be end)) over (partition by vt),
       sum(sum(be)) over (partition by vk),
       sum(sum(case when au = 8 then be end)) over (partition by vk),
       sum(sum(be)) over (partition by gp),
       sum(sum(case when au = 8 then be end)) over (partition by gp)
from aux
group by vt, vk, gp;
 

Вот скрипка db<>.