как рассчитать процент условной агрегации - PullRequest
2 голосов
/ 31 января 2020

У меня есть таблица данных, см. http://sqlfiddle.com/#! 4 / cf72da / 5 Используя сводную инструкцию, я могу разбить счет по заголовку

select division, status, 
       sum(case when title = 'worker' then 1 else 0 end) as workerCount,
       (sum(case when title = 'worker' then 1 else 0 end) /
        sum(sum(case when title = 'worker' then 1 else 0 end)) over ()
       )*100 as workerPercent
from ta
group by status, division
order by division, status

Таким образом, результат выглядит следующим образом:

DIVISION  STATUS    WORKERCOUNT  WORKERPERCENT
11        ready     3            30
11        started   3            30
12        finished  4            40
12        ready     0            0
12        started   0            0

Мне действительно нужны проценты, деленные на деление, например

DIVISION  STATUS    WORKERCOUNT  WORKERPERCENT
11        ready     3            50
11        started   3            50
12        finished  4            100
12        ready     0            0
12        started   0            0

Любая идея, как я могу выполнить sh это с SQL?

Ответы [ 4 ]

0 голосов
/ 31 января 2020

Как отмечали другие авторы, вы можете (и должны) использовать функции analyti c для решения этой проблемы.

Специально для вашего случая есть функция RATIO_TO_REPORT - гораздо лучше использовать его, чем вычислять вещи «вручную», как в вашей попытке и в нескольких ответах.

Обратите внимание на еще одно внесенное мной изменение - сумма 1, когда «работник» и 0 «в противном случае» совпадает со счетом «работник». ». COUNT гораздо понятнее, чем SUM в этом контексте.

select division, status, 
       count(case when title = 'worker' then 1 end) as workerCount,
       ratio_to_report(count(case when title = 'worker' then 1 end))
           over (partition by division)*100 as workerPercent
from  ta
group by status, division
order by division, status;

Спасибо за публикацию данных теста и вашу попытку - это очень полезно!

0 голосов
/ 31 января 2020

Вам не хватает пункта analyti c :

select division, status, 
       count(decode(title,'worker',1,null)) as workerCount,
       ( count(decode(title,'worker',1,null))
       / sum(count(decode(title,'worker',1,null))) over(partition by division)
       )*100 as workerPercent
from ta
group by status, division
order by division, status
0 голосов
/ 31 января 2020

Вы очень близки к ожидаемому результату.

Вам просто нужно добавить предложение partition by в analytical function следующим образом:

SQL> SELECT
  2      DIVISION,
  3      STATUS,
  4      SUM(CASE WHEN TITLE = 'worker' THEN 1 ELSE 0 END) AS WORKERCOUNT,
  5      ( SUM(CASE WHEN TITLE = 'worker' THEN 1 ELSE 0 END) /
  6              SUM(SUM(CASE WHEN TITLE = 'worker' THEN 1 ELSE 0 END))
  7                  OVER( PARTITION BY DIVISION )  -- Changes here
  8      ) * 100 AS WORKERPERCENT
  9  FROM TA
 10  GROUP BY STATUS, DIVISION
 11  ORDER BY DIVISION, STATUS;

  DIVISION STATUS               WORKERCOUNT WORKERPERCENT
---------- -------------------- ----------- -------------
        11 ready                          3            50
        11 started                        3            50
        12 finished                       4           100
        12 ready                          0             0
        12 started                        0             0

SQL>

SQL Демонстрация скрипки

Приветствия !!

0 голосов
/ 31 января 2020

Используйте следующий запрос:

select division, status, 
       sum(case when title = 'worker' then 1 else 0 end) as workerCount,
       (sum(case when title = 'worker' then 1 else 0 end) /
        sum(sum(case when title = 'worker' then 1 else 0 end)) over (PARTITION BY division)
       )*100 as workerPercent
from ta
group by status, division
order by division, status
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...