上一篇咱们介绍了三个常用的排序函数row_number(),rank()和dense_rank()。这三个函数需要配合开窗函数over()来实现排序功能。但over()的用法远不止于此,本文咱们来介绍如何实现累计求和和滑动求和。

1、数据介绍

咱们有三列数据,分别是员工的姓名、月份和销售额:

接下来,咱们实现两个主要的功能,对每个员工的销售业绩的累积求和以及滑动求和(每个月计算其最近三个月的总销售业绩)

2、累积求和

实现累积求和,使用sum()函数配合over()来实现,具体的实现语法如下:

 sum(需要求和的列) over(partition by 分组列 order by 排序列 asc/desc)
 

本例中的SQL代码如下:

select
 sum(cnt) over(partition by name order by month) as total_cnt
 default.salerinfo
 

结果如下:

3、滑动求和

累积求和还是比较简单的,滑动求和就需要用到over中的另一用法了:

 sum(需要求和的列) over(partition by 分组列 order by 排序列 range between ... and ...)
 

这里需要在over函数中使用range between and指定窗口的大小,向前使用preceding,向后使用following。如2 preceding and 1 following指定的窗口包括当前行、当前行前面两行以及当前行后面一行,总共4行。

如在本例中,我们想要求每个月对应的最近三个月的业绩之和(包含本月在内),代码如下:

sum(cnt) over(partition by name order by month range between 2 preceding and 0 following) 
 

如果不想写0 following,另一种更为合适的写法是使用current row:

sum(cnt) over(partition by name order by month range between 2 preceding and current row)
 

两种写法都是可以的,结果如下:

可以看到,在前面的数据不足两行时,有几行就对几行求和。如1月份的滑动求和即本身,2月份的求和结果时1月份和2月份的累积。

更进一步,如果我们想实现不包含本月在内的前三个月的求和,该怎么实现呢?一种是使用4行的滑动求和减去当前行的结果,另一种是range两边都使用preceding:

select
 sum(cnt) over(partition by name order by month range between 3 preceding and 1 preceding) as total_cnt
 default.salerinfo
 

当然,可以调皮一下,把1 preceding换成 -1 following也可以,二者是等价的:

sum(cnt) over(partition by name order by month range between 3 preceding and -1 following)
 

结果如下:

有没有学到新东西呢~~~

rows是物理窗口,是哪一行就是哪一行,与当前行的值(order by key的key的值)无关,只与排序后的行号相关,就是我们常规理解的那样。range是逻辑窗口,与当前行的值有关(order by key的key的值),在key上操作range范围。 简要:如果当前行的值有重复的,range会默认把重复的值加一块,rows是按照行号来,是哪一行就是哪一行 不加行号默认是按照range,id都为1的话, 会把1的加一块
**tip:**在hive,如果从分析出计算当前的数据跟之前的状态数据有关(比如漏斗模型算转化率)--------->先把自己跟自己join–>就会把自己当前的状态数据跟之前的状态数据join起来出现在一行。 create table t_salary_detail(username string,month string,salary int) row format de...
sum(列1) : 这一列直接求和的时候遇到NULL值是会忽略不计的 avg(列1) : 直接求平均值的时候遇到NULL值也是忽略不计,其他有值的正常计算 列1+列2:如果两列里有其一列为NULL的话,那么结果就是为null的 count(列1):如果列1里边有NULL的话是不进行计算的 count(*) :在进行统计计数的时候,所有的列都进行计算,包括NULL也算 1-函数对NULL值的求和求平均 首先来看这段代码 with temp as (select null
1、hive的子查询 where 条件里不支持不等式子查询,实际上是支持 in、not in、exists、not exists select * from students where clazz in(select clazz from students as t where t.id=‘1 500100970’); //注意2张表是相同的,需要加标识,就是给表命名,区分 2、字段相加函数 字段含有null值,使用nvl函数 eg:select id,nvl(x,0) from vels; //x为nu
create table t_access_times(username string,month string,salary int) row format delimited fields terminated by ‘,’; load data local inpath ‘/home/hujian/t_access_times.dat’ into table t_access_times; 欢迎使用Markdown编辑器 通过分析题目,我们发现shop_id相同的a列相加之和正好为1,因此我们可以分析得a列应该是根据shiop_id分组的某个百分比,再根据表数据得是每列num所占总和num的百分比;而b列则是根据shop_id分组的a列排名. 分析完需求后,我们就可以着手写h...