如何计算百分比条件聚合

Posted

技术标签:

【中文标题】如何计算百分比条件聚合【英文标题】:how to calculate percent conditional aggregation 【发布时间】:2020-01-31 03:44:40 【问题描述】:

我有一张数据表,见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

知道如何使用 SQL 完成此任务吗?

【问题讨论】:

【参考方案1】:

使用以下查询:

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

【讨论】:

【参考方案2】:

您缺少分析子句

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

【讨论】:

【参考方案3】:

您已经非常接近预期的结果了。

您只需在analytical function 中添加partition by 子句,如下所示:

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 Fiddle demo

干杯!!

【讨论】:

【参考方案4】:

正如其他发帖者所指出的,您可以(并且应该)使用分析函数来解决这类问题。

专门针对您的用例,有 RATIO_TO_REPORT 函数 - 使用它比在您的尝试和几个答案中“手动”计算事物要好得多。

请注意我所做的另一项更改 - “工人”和 0 “否则”时的总和与计算“工人”相同。在这种情况下,COUNTSUM 清晰得多。

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;

感谢您发布测试数据和您的尝试 - 这非常有帮助!

【讨论】:

以上是关于如何计算百分比条件聚合的主要内容,如果未能解决你的问题,请参考以下文章

在计算百分比时将 Over() 与聚合函数一起使用

如何计算 Spark SQL 中满足特定条件的总数百分比

用于执行聚合和计算百分比的 SQL 查询

当存在 2 个分组条件时如何计算 mysql/sql 中的百分比

excel如何计算占总数的百分比

查找 SQL 聚合函数调用中的百分比可能没有嵌套聚合或窗口函数