Hive窗口函数 row_number over()和sum() over()的使用详解

row_number over()的使用:

假如我们有这样一组数据,我们需要求出不同性别的年龄top2的人的信息。这个时候怎么做?
可能我们会首先想到分组,但是分组只能值top1,怎么样能求出top2,top3呢?这时候我们想如果分组后能够按照年龄排序然后标出来序号就好了!

id   age  name sex

1,18,xiaoli,male
2,19,wang,male
3,22,liu,female
4,16,dawei,male
5,30,erbao,male
6,26,xiao,female
7,18,chengua,male

下面就介绍一个非常有用的函数:row_number() over()他的作用就是分组排序加上序号标记
比如以上求解不同性别的年龄top2,我们可以这样做:
建表导入数据:

create table rownumber(id string,age int,name string,sex string)
row format delimited
fields terminated by ',';
load data local inpath '/root/mytest/rowover.dat' into table rownumber;

select id,age,name,sex,
row_number() over(partition by sex order by age desc) as rownumber
from rownumber;


我们可以清楚的看到 row_number() over(partition by sex order by age desc) as rownumber
就相当于增加了一列序号,over()中partition by sex是按照sex分组,order by age desc按照年龄降序排序,然后row_number()在加上序号。

select id,age,name,sex
from
(select id,age,name,sex,
row_number() over(partition by sex order by age desc) as rownumber
from rownumber ) temp
where rownumber<3;


这样就求出分组topn了,很方便!

sum() over()的使用:

有这样的数据:第一列name,第二列月份mon,第三列金额jine
A,2015-01,5
A,2015-01,15
B,2015-01,5
A,2015-01,8
B,2015-01,25
A,2015-01,5
C,2015-01,10
C,2015-01,20
A,2015-02,4
A,2015-02,6
C,2015-02,30
C,2015-02,10
B,2015-02,10
B,2015-02,5
A,2015-03,14
A,2015-03,6
B,2015-03,20
B,2015-03,25
C,2015-03,10
C,2015-03,20

我们需要求出对于每个人的一个月的总额和累计到当前月的总额。
传统方法非常的麻烦,具体思路是;先求出月总额表(name,mon,amount),然后讲月总额表自联结,在过滤当前月份后面的月份,最终在求和。
使用sum() over()可以轻松给解决,sum()首先我们都知道是求和,加上over()就是针对某个窗口求和了,具体哪个窗口呢?
具体实现:
求出每月的总额 放到表中,先将数据加载到表中,在求月总额

create table monsum(name string,mon string,jine string)
row format delimited
fields terminated by ',';
load data local inpath '/root/mytest/sumreport.dat' into table monsum;
 
--求出月总额
create table monamount 
as
select name,mon,sum(jine) as amount
from monsum
group by name,mon;


然后使用窗口函数求出累计当前月总额,

select name,mon,amount,
sum(amount) over(partition by name order by mon rows between unbounded preceding and current row) as account
from monamount;


sum(amount)的求和是针对后面over()窗口的求和,
over中partition by name order by mon 针对name这一组按照月份排序,rows between unbounded preceding and current 限定了行是按照在当前行不限定的往前处理,通俗就是处理当前以及之前的所有行的sum,即3月时sum(amount)求的时123月的和,2月时sum(amount)求的是12月的和。unbounded意思无限的 preceding在之前的,current row当前行。

原文地址:https://www.cnblogs.com/sjkzy/p/15089708.html