窗口函数:计算环比和同比

0 前言

        环比,表示连续2个单位周期(比如连续两月)内的量的变化比,反映本期比上期增长了多少; 计算公式:环比增长率=(本期数-上期数)/上期数×100%,例如某商城2018年2月份销售额比2018年1月份销售额增长了多少。

       同比一般情况下是今年第n月与去年第n月比,用以说明本期发展水平与去年同期发展水平对比而达到的相对发展速度,计算公式:同比增长速度=(本期发展水平-去年同期水平)/去年同期水平×100%,例如某商城2019年1月份比2018年1月份销售额增长了多少等。

       使用sql计算环比和同比的时候,查看了大多数人都是通过表嵌套表计算环比和同比,这里同样,我们使用几行简单的窗口函数来计算环比和同比。

2 需求描述

构造一些数据集,例如,下面是某公司在不同地区,不同省份的销售额:

不同季节销售额
日期 地区 省份 销售额
2017/12 华东 上海市 3600000
2017/12 华东 江苏省 2800000
2017/12 华东 浙江省 4500000
2017/12 华北 北京市 3000000
2017/12 华北 天津市 2800000
2018/01 华东 上海市 3000000
2018/01 华东 江苏省 2000000
2018/01 华东 浙江省 2500000
2018/01 华北 北京市 2600000
2018/01 华北 天津市 1500000
2018/02 华东 上海市 3500000
2018/02 华东 江苏省 2100000
2018/02 华东 浙江省 2400000
2018/02 华北 北京市 2800000
2018/02 华北 天津市 2000000
2018/03 华东 上海市 2900000
2018/03 华东 江苏省 2800000
2018/03 华东 浙江省 2900000
2018/03 华北 北京市 3500000
2018/03 华北 天津市 3000000
2018/04 华东 上海市 2900000
2018/04 华东 江苏省 3000000
2018/04 华东 浙江省 2800000
2018/04 华北 北京市 3000000
2018/04 华北 天津市 2500000

 

我们的需求是:

(1)求不同地区不同省份每个季节的环比是多少?

(2)求不同地区不同省份每个季节的同比是多少?

2  需求实现

2.1 插入数据

       假定已经构建一个表明为new_table含有date、area、province和saleroom四个字段:date表示年度季节,area表示地区,province表示省份,saleroom表示销售额。插入数据:

insert into new_table values ('2017/12', '华东',     '上海市',   '3600000');
insert into new_table values ('2017/12', '华东', 	'江苏省',	'2800000');
insert into new_table values('2017/12',  '华东', 	'浙江省',	'4500000');
insert into new_table values('2017/12',  '华北', 	'北京市',	'3000000');
insert into new_table values('2017/12',  '华北', 	'天津市',	'2800000');
insert into new_table values('2018/01',  '华东', 	'上海市',	'3000000');
insert into new_table values('2018/01',  '华东', 	'江苏省',	'2000000');
insert into new_table values('2018/01',  '华东', 	'浙江省',	'2500000');
insert into new_table values('2018/01',  '华北', 	'北京市',	'2600000');
insert into new_table values('2018/01',  '华北', 	'天津市',	'1500000');
insert into new_table values('2018/02',  '华东', 	'上海市',	'3500000');
insert into new_table values('2018/02',  '华东', 	'江苏省',	'2100000');
insert into new_table values('2018/02',  '华东', 	'浙江省',	'2400000');
insert into new_table values('2018/02',  '华北', 	'北京市',	'2800000');
insert into new_table values('2018/02',  '华北', 	'天津市',	'2000000');
insert into new_table values('2018/03',  '华东', 	'上海市',	'2900000');
insert into new_table values('2018/03',  '华东', 	'江苏省',	'2800000');
insert into new_table values('2018/03',  '华东', 	'浙江省',	'2900000');
insert into new_table values('2018/03',  '华北', 	'北京市',	'3500000');
insert into new_table values('2018/03',  '华北', 	'天津市',	'3000000');
insert into new_table values('2018/04',  '华东', 	'上海市',	'2900000');
insert into new_table values('2018/04',  '华东', 	'江苏省',	'3000000');
insert into new_table values('2018/04',  '华东', 	'浙江省',	'2800000');
insert into new_table values('2018/04',  '华北', 	'北京市',	'3000000');
insert into new_table values('2018/04',  '华北', 	'天津市',	'2500000');

梳理思路:

       计算环比:首先需要将不同地区不同省份的销售额按季节单位排需,然后计算连续2个单位周期销售额环比;

       计算同比:首先需要将不同地区不同省份的销售额按年度单位排序,然后计算连续2个单位周期销售额同比;

两个共同的特点是:第一步:按照不同地区不同省份分组,按照时间进行排序,第二步:将相邻的两行进行计算,所有可以使用窗口函数lead()函数实现。

2.2 需求实现:

    环比计算:

select date, area, province, saleroom,
    lead(saleroom,1) over(partition by area, province order by date desc) lead_saleroom
provinfrom provincnew_table;

   我们得到下表数据:

     

date area province saleroom lead_saleroom
2018/04 华东 上海市 2900000 2900000
2018/03 华东 上海市 2900000 3500000
2018/02 华东 上海市 3500000 3000000
2018/01 华东 上海市 3000000 3600000
2017/12 华东 上海市 3600000 NULL
2018/04 华东 江苏省 3000000 2800000
2018/03 华东 江苏省 2800000 2100000
2018/02 华东 江苏省 2100000 2000000
2018/01 华东 江苏省 2000000 2800000
2017/12 华东 江苏省 2800000 NULL
2018/04 华东 浙江省 2800000 2900000
2018/03 华东 浙江省 2900000 2400000
2018/02 华东 浙江省 2400000 2500000
2018/01 华东 浙江省 2500000 4500000
2017/12 华东 浙江省 4500000 NULL
2018/04 华北 北京市 3000000 3500000
2018/03 华北 北京市 3500000 2800000
2018/02 华北 北京市 2800000 2600000
2018/01 华北 北京市 2600000 3000000
2017/12 华北 北京市 3000000 NULL
2018/04 华北 天津市 2500000 3000000
2018/03 华北 天津市 3000000 2000000
2018/02 华北 天津市 2000000 1500000
2018/01 华北 天津市 1500000 2800000
2017/12 华北 天津市 2800000 NULL

不同地区不同省份的环比为:(saleroom - lead_saleroom)/ lead_saleroom,所以最终代码为:

select *, 
(saleroom - lead_saleroom)/lead_saleroom huanbi
from 
(select date, area, city, saleroom,
    lead(saleroom,1) over(partition by area, province order by date desc) lead_saleroom
    from lianxi.new_table) t
where lead_saleroom is not null

得到环比:

date area province saleroom lead_saleroom 环比
2018/04 华东 上海市 2900000 2900000 0.00%
2018/03 华东 上海市 2900000 3500000 -17.14%
2018/02 华东 上海市 3500000 3000000 16.67%
2018/01 华东 上海市 3000000 3600000 -16.67%
2018/04 华东 江苏省 3000000 2800000 7.14%
2018/03 华东 江苏省 2800000 2100000 33.33%
2018/02 华东 江苏省 2100000 2000000 5.00%
2018/01 华东 江苏省 2000000 2800000 -28.57%
2018/04 华东 浙江省 2800000 2900000 -3.45%
2018/03 华东 浙江省 2900000 2400000 20.83%
2018/02 华东 浙江省 2400000 2500000 -4.00%
2018/01 华东 浙江省 2500000 4500000 -44.44%
2018/04 华北 北京市 3000000 3500000 -14.29%
2018/03 华北 北京市 3500000 2800000 25.00%
2018/02 华北 北京市 2800000 2600000 7.69%
2018/01 华北 北京市 2600000 3000000 -13.33%
2018/04 华北 天津市 2500000 3000000 -16.67%
2018/03 华北 天津市 3000000 2000000 50.00%
2018/02 华北 天津市 2000000 1500000 33.33%
2018/01 华北 天津市 1500000 2800000 -46.43%

同样的操作可以计算同比,只需要按照年份排序即可:

select *, 
(saleroom - lead_saleroom)/lead_saleroom tongbi
from 
(select date, area, city, saleroom,
    lead(saleroom,1) over(partition by area, province order by substr(date,1,4) desc) lead_saleroom
    from lianxi.new_table) t
where lead_saleroom is not null

3 总结

       这里分享了使用窗口函数计算环比和同比,再次见识到了窗口函数的强大之处,后续我们分析一下使用窗口函数做vintage报表。

                                                                                  窗口函数:计算环比和同比_第1张图片

                                                                     

你可能感兴趣的:(窗口函数:计算环比和同比)