窗口函数:实现组内百分比、累计值、累计百分比

0 前言

        最近做数据分析,需要求每一组内的元素的百分比以及累计百分比,实在想不出怎么使用sql实现,就先将数据导出,然后使用excel计算。趁着夜深人静的时候,思维敏捷,尝试一下使用窗口函数实现一下,天佑我也,尝试了几次,最终成功了,这里分享一下,也算抛砖引玉,如果有更好的方法,可以共同交流一下。

1 需求描述

   还是以往风格,直接用表格描述需求,虚构一些数据,某公司在每个地区不同月份的销售额如下:

  我们需要在表1的后面加上3列:分别是组内百分比、组内累计值和组内累计百分比。

                                                       表 1
地区年月销售额
A2018/041000000
A2018/052000000
A2018/061500000
B2018/041000000
B2018/051600000
B2018/062000000
B2018/071500000
                                                        表   2
地区年月销售额组内百分比组内累积值组内累积百分比
A2018/04100000022.22%100000022.22%
A2018/05200000044.44%300000066.67%
A2018/06150000033.33%4500000100.00%
B2018/04100000016.39%100000016.39%
B2018/05160000026.23%260000042.62%
B2018/06200000032.79%460000075.41%
B2018/07150000024.59%6100000100.00%

 

2  需求实现

     可以看出A地区3个月的销售总额为4500000,那么组内百分比分别为1000000/4500000、2000000/4500000和1500000/4500000,同理可以得到B地区的,但是在sql中怎么计算A地区和B地区的销售总额呢?可能你会想到group by一下地区,然后对每个地区销售额求和,可以求出来,但是个人觉得那样就比较繁琐了,写sql代码应该是一种享受的过程。这里我们使用窗口函数实现我们的需求:及加入一个字段sum(saleroom) over(partition by area order by area)即可。

    组内累计和和组内累计百分比比较棘手,尝试了一些办法,分享一些认为比较简单的代码。

2.1 实现代码

      为了呈现百分比的结果,我们使用round()函数以及concat()函数对小数结果进行处理,当然如果觉得输入结果为字符型,你也可以使用cast()函数进行转化格式:

sum(saleroom) over(partition by area order by date) ---求组内累计值
sum(saleroom) over(partition by area order by area)	---求组内总计值


select *,
    sum(saleroom) over(partition by area order by date) aggregate_value,
    sum(saleroom) over(partition by area order by area) total_vale
from WN_table1;
    

运行结果见表3:

                                     表 3 组内累计值和组内总计
areadatesaleroomaggregate_valuetotal_value
A2018/04100000010000004500000
A2018/05200000030000004500000
A2018/06150000045000004500000
B2018/04100000010000006100000
B2018/05160000026000006100000
B2018/06200000046000006100000
B2018/07150000061000006100000

所以,

        组内百分比= saleroom / total_value

       累计百分比 = aggregate_value/total_value

故得到表2格式的代码如下:

select area, date, saleroom, 
      concat(round((saleroom /total_value)*100,2), '%') percent,
      aggregate_value,
      concat(round((aggregate_value/total_value)*100,2), '%') aggregate_percent
from
    (select *,
        sum(saleroom) over(partition by area order by date) aggregate_value,
        sum(saleroom) over(partition by area order by area) total_value
        from WN_table1
    ) t
    

3 总结

         本文分享使用窗口函数实现一些复杂的需求,日后会陆续写一些有关窗口函数的内容,有时间的话,将窗口函数知识系列分享一些下,晚安,everyone。

 


版权声明:本文为weixin_39751959原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。