如何在 Snowflake 中旋转多个聚合

Vip*_*ngh 3 sql snowflake-cloud-data-platform

我的表结构如下

产品编号 时期 销售量 利润
x1 L13 100 美元 10 美元
x1 L26 200 美元 20 美元
x1 L52 300 美元 30 美元
x2 L13 500 美元 110 美元
x2 L26 600 美元 120 美元
x2 L52 700 美元 130 美元

我想旋转期间列并在这些列中显示销售价值和利润。我需要一张如下表。

产品编号 销售_L13 销售_L26 销售_L52 利润_L13 利润_L26 利润_L52
x1 100 美元 200 美元 300 美元 10 美元 20 美元 30 美元
x2 500 美元 600 美元 700 美元 110 美元 120 美元 130 美元

我正在使用雪花来编写查询。我尝试使用pivot雪花函数,但只能指定一个聚合函数。

任何人都可以帮助我如何实现这个解决方案?

任何帮助表示赞赏。

谢谢

Phi*_*son 6

在转向之前我们先将销售额和利润叠加起来怎么样?我将由您来修复我弄乱的列名称。

with cte (product_id, period, amount) as
  
(select product_id, period||'_profit', profit from t
 union all
 select product_id, period||'_sales', sales from t)
   
select * 
from cte
     pivot(max(amount) for period in ('L13_sales','L26_sales','L52_sales','L13_profit','L26_profit','L52_profit'))
     as p (product_id,L13_sales,L26_sales,L52_sales,L13_profit,L26_profit,L52_profit);
Run Code Online (Sandbox Code Playgroud)

如果您希望对销售额和利润进行两次数据透视,则需要复制该列,以便每个数据透视实例都有一个列。显然,这将创建空值,因为在第一个数据透视之后仍然存在重复列。为了解决这个问题,我们可以max在最终选择中使用。这是实现的样子

select product_id, 
       max(L13_sales) as L13_sales, 
       max(L26_sales) as L26_sales, 
       max(L52_sales) as L52_sales, 
       max(L13_profit) as L13_profit, 
       max(L26_profit) as L26_profit, 
       max(L52_profit) as L52_profit
from (select *, period as period2 from t) t
      pivot(max(sales) for period in ('L13','L26','L52'))
      pivot(max(profit) for period2 in ('L13','L26','L52'))  
      as p (product_id, L13_sales,L26_sales,L52_sales,L13_profit,L26_profit,L52_profit)
group by product_id;
Run Code Online (Sandbox Code Playgroud)

此时,就显得碍眼了。您不妨使用conditional aggregation或更好的是在报告应用程序内处理数据透视。更紧凑的conditional aggregation用途替代方案decode

select product_id,
       max(decode(period,'L13',sales)) as L13_sales,
       max(decode(period,'L26',sales)) as L26_sales,
       max(decode(period,'L52',sales)) as L52_sales,
       max(decode(period,'L13',profit)) as L13_profit,
       max(decode(period,'L26',profit)) as L26_profit,
       max(decode(period,'L52',profit)) as L52_profit
from t
group by product_id;
Run Code Online (Sandbox Code Playgroud)