将分析函数与汇总相结合

Posted

技术标签:

【中文标题】将分析函数与汇总相结合【英文标题】:Combining Analytic Functions with Rollup 【发布时间】:2021-11-14 06:41:28 【问题描述】:

我可以使用GROUP BY ROLLUP 获得聚合小计,并且我可以使用分析函数获得% of Parent 和其他类似计算,即OVER()。但是,我很难将这两者结合起来。例如,尝试在下面获取 Parent for Profit 的百分比:

with SalesX as (
    select 'Office Supplies' Category , 2014 Year,22593.42 Profit UNION all
    select 'Technology', 2014, 21492.83 UNION all
    select 'Furniture', 2014,   5457.73 UNION all
    select 'Office Supplies',   2015,   25099.53  UNION all
    select 'Technology',    2015,   33503.87  UNION all
    select 'Furniture', 2015,   50000.00  UNION all
    select 'Office Supplies',   2016,   35061.23  UNION all
    select 'Technology',    2016,   39773.99  UNION all
    select 'Furniture', 2016,   6959.95
) 
select category, year, Profit, SUM(Profit) OVER (partition by category)
from (
SELECT
    category,
    year,
    SUM(profit) Profit
FROM SalesX group by rollup(category, year) order by category
) _

由于汇总,我们可以在这里看到它“双重计数”:

解决这个问题的正确方法是什么?

【问题讨论】:

在这里查看实际预期输出会非常有帮助。否则,可能不是每个人都清楚你想要什么。 @TimBiegeleisen 是的,同意。当我从 Excel 中尝试复制查询中的功能时,我很难写出我想要得到的东西。我已经发布了我使用的答案。 @TimBiegeleisen 请务必回复。 【参考方案1】:

BigQuery 不支持 GROUPING 函数来查看聚合值是否为小计,但假设 NULL 值始终表示总计,我们可以将各种 CASEs 串在一起以排除小计行:

with SalesX as (
    select 'Office Supplies' Category , 2014 Year,22593.42 Profit UNION all
    select 'Technology', 2014, 21492.83 UNION all
    select 'Furniture', 2014,   5457.73 UNION all
    select 'Office Supplies',   2015,   25099.53  UNION all
    select 'Technology',    2015,   33503.87  UNION all
    select 'Furniture', 2015,   50000.00  UNION all
    select 'Office Supplies',   2016,   35061.23  UNION all
    select 'Technology',    2016,   39773.99  UNION all
    select 'Furniture', 2016,   6959.95
) 
select category, year, Profit,
    Profit / SUM(CASE WHEN category is null or year is null then null else Profit end) OVER (partition by category) as CategoryPercent,
    Profit / SUM(CASE WHEN category is null or year is null then null else Profit end) OVER () as GrandPercent
from (
SELECT
    category,
    year,
    SUM(profit) Profit
FROM SalesX group by rollup(category, year) order by category
) _

这为我们提供了我们正在寻找的东西:

【讨论】:

以上是关于将分析函数与汇总相结合的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 基础知识汇总(知识与实践相结合)

Kotlin 基础知识汇总(知识与实践相结合)

将 postgres 函数与查询相结合

在 Apache Spark 中将批处理 RDD 的结果与流式 RDD 相结合

Socket与系统调用深度分析

山东大学软件工程应用与实践——GMSSL开源库——SM9数字签名算法及验证的源代码分析