在Presto/Athena中计算分组后各记录的占比及累计百分比
在Presto/Athena中计算分组后的用户假期天数占比与累计百分比
我来帮你解决这个分析需求,这是业务中很常见的占比统计场景,咱们直接上可执行的方案:
完整查询语句
WITH grouped_holidays AS ( SELECT AccountID, UserID, SUM(HolidaysTaken) AS HolidaysTaken FROM table WHERE AccountID = 'ABC' GROUP BY AccountID, UserID ), total_holidays AS ( SELECT *, SUM(HolidaysTaken) OVER (PARTITION BY AccountID) AS TotalAccountHolidays FROM grouped_holidays ) SELECT AccountID, UserID, HolidaysTaken, ROUND((HolidaysTaken / TotalAccountHolidays) * 100, 2) AS EachUserPercentage, ROUND(SUM((HolidaysTaken / TotalAccountHolidays) * 100) OVER ( PARTITION BY AccountID ORDER BY HolidaysTaken DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ), 2) AS CumulativePercentage FROM total_holidays ORDER BY HolidaysTaken DESC;
分步解释
分组计算用户累计假期
第一个CTEgrouped_holidays就是你之前写的分组查询,用来得到每个用户的总假期天数,结果和你提供的分组数据一致。计算账户总假期
第二个CTEtotal_holidays用窗口函数SUM(HolidaysTaken) OVER (PARTITION BY AccountID)计算整个账户的总假期天数(这里就是19),这样每一行数据都能拿到这个全局总数值,方便后续计算占比。计算占比与累计占比
EachUserPercentage:用当前用户的假期天数除以账户总假期,乘以100后用ROUND函数保留两位小数,得到用户个人假期的占比。CumulativePercentage:用SUM()窗口函数,指定按假期天数降序排序,窗口范围设为UNBOUNDED PRECEDING AND CURRENT ROW(从第一行到当前行),这样就能逐行累加前面所有用户的占比,最终得到累计百分比。
为什么percent_rank()等函数不适用?
你提到的percent_rank()、cume_dist()这类窗口函数是基于行的相对位置计算的,比如cume_dist()返回的是当前行及之前的行数占总行数的比例,而不是实际假期数值的占比,完全不符合你的业务需求。咱们需要的是基于实际数值的占比统计,所以必须手动计算占比后再做累计求和。
预期执行结果
| AccountID | UserID | HolidaysTaken | EachUserPercentage | CumulativePercentage |
|---|---|---|---|---|
| ABC | B | 9 | 47.36 | 47.36 |
| ABC | K | 5 | 26.31 | 73.67 |
| ABC | A | 4 | 21.05 | 94.72 |
| ABC | X | 1 | 5.26 | 100.00 |
内容的提问来源于stack exchange,提问作者Ranveer Singh
相关产品推荐
相关产品推荐

