Как я могу написать эквивалентный SQL-запрос для поворота со сложными агрегациями в базе данных оракула?

В Spark мы можем предоставить сложные агрегаты с осью. например

project.groupBy("mgr","job").pivot("job").agg(sum(project.col("salary")).alias("ss") * count("*").alias("c"))

Данные ниже, т.е. проект

mgr deptno salary job
APAC 10 100 CLERK
APAC 20 200 MANAGER
APAC 20 300 CLERK
APAC 10 400 CLERK
JPAC 20 1000 CLERK
JPAC 10 2000 MANAGER
EMEA 20 10000 CLERK
EMEA 20 40000 MANAGER
EMEA 20 30000 CLERK

Вывод :

mgr job CLERK MANAGER
EMEA MANAGER null 40000
JPAC MANAGER null 2000
EMEA CLERK 80000 null
JPAC CLERK 1000 null
APAC CLERK 2400 null
APAC MANAGER null 200

Могу ли я написать аналогичный SQL-запрос, используя сводную базу данных оракула?


person Ashutosh    schedule 06.03.2021    source источник
comment
Выходная сводка зарплаты не соответствует входной таблице. для EMEA зарплата КЛЕРА будет 40000(10000+30000) вместо 80000.   -  person Kazi Mohammad Ali Nur    schedule 06.03.2021
comment
Это сумма * Посчитайте правильно. Итак 40000*2.   -  person Ashutosh    schedule 06.03.2021
comment
Хорошо понял. Теперь меняю свой запрос   -  person Kazi Mohammad Ali Nur    schedule 06.03.2021


Ответы (2)


Вот две версии того, что вам нужно (надеюсь, обе вам помогут):

Запрос №1

select * from (
select mgr,job,salary from project
)
pivot
(
    sum(salary)
    for job in ('CLERK','MANAGER')
)

Вывод №1

MGR     JOB      'CLERK'    'MANAGER'
JPAC    CLERK    1000    - 
JPAC    MANAGER   -          2000
APAC    CLERK    800         - 
APAC    MANAGER   -          200
EMEA    CLERK    40000   - 
EMEA    MANAGER   -          40000

Запрос №2:

select * from (
select mgr,job,salary from project
)
pivot
(
    sum(salary)
    for Job  in ('CLERK','MANAGER')
)

Вывод №2:

MGR    'CLERK'  'MANAGER'
EMEA    40000    40000
APAC    800      200
JPAC    1000     2000

*Запрос №3 (SUM()COUNT()):

select * from (
select mgr,job,job JobToPivot,sum(salary)*count(*) salary from project
group by mgr,job
)
pivot
(
    max(salary)
    for JobToPivot  in ('CLERK','MANAGER')
)

Вывод №3:

MGR     JOB     'CLERK' 'MANAGER'
JPAC    CLERK    1000    - 
JPAC    MANAGER  -       2000
APAC    CLERK    2400    - 
APAC    MANAGER  -       200
EMEA    CLERK    80000   - 
EMEA    MANAGER  -       40000

*Запрос №4 (sum()COUNT()):

select * from (
select mgr,job,sum(salary)*count(*) salary from project
group by mgr,job
)
pivot
(
    max(salary)
    for Job  in ('CLERK','MANAGER')
)

Вывод №4:

MGR    'CLERK'  'MANAGER'
EMEA    80000   40000
APAC    2400    200
JPAC    1000    2000
person Kazi Mohammad Ali Nur    schedule 06.03.2021
comment
В искровом запросе предоставленная агрегация представляет собой сумму (project.col(salary)).alias(ss) * count(*).alias(c). Таким образом, нам понадобится сумма и подсчет как в SQL-запросе. - person Ashutosh; 06.03.2021
comment
Пожалуйста, посмотрите сейчас. - person Kazi Mohammad Ali Nur; 06.03.2021
comment
Я думаю, что Query 4 нуждается в некоторых модификациях, например, псевдоним может использоваться с суммой (зарплатой) count(), а некоторые функции, такие как max, могут быть переданы как агрегат внутри свода. Поэтому выберите * из ( выберите управляющий, работа, сумма (зарплата) * количество () как оклад sum_count из группы проектов по управляющему, заданием) сводной ( макс (сумма_счет) для работы в ('КЛЕРК','МЕНЕДЖЕР' )) может быть правильным запросом. - person Ashutosh; 06.03.2021
comment
Так как ответ был правильным, торопился не заметил. Я изменил свой ответ в соответствии с вашим предложением. - person Kazi Mohammad Ali Nur; 07.03.2021

Ваш набор результатов не имеет для меня смысла. Не будет ли один из них более полезным?

select mgr, job, sum(salary)
from project
group by mgr, job;

Это создает отдельную строку для каждого mgr и job, но только для одной зарплаты.

Or:

select mgr,
       sum(case when job = 'CLERK' then salary end) as clerk,
       sum(case when job = 'MANAGER' then salary end) as manager
from project
group by mgr;

Это имеет одну строку на mgr с зарплатами, заполненными в обоих столбцах зарплат.

Оба они являются стандартным SQL (в отличие от pivot) и должны работать в любой базе данных.

person Gordon Linoff    schedule 06.03.2021
comment
Ты прав. Мы можем реализовать сводку с помощью (агрегат + фильтры) без использования ключевого слова сводки. И это будет работать в любой базе данных. То, что я пытаюсь сделать, похоже на искру, если мы можем обеспечить сложные агрегаты с поворотом в sql. - person Ashutosh; 06.03.2021