hive查询之开窗函数

学习hive的开窗函数,顺便总结一番:

普通的聚合函数聚合的行集是组,开窗函数聚合的行集是窗口。因此,普通的聚合函数每组(Group by)只返回一个值,而开窗函数则可为窗口中的每行都返回一个值。简单理解,就是对查询的结果多出一列,这一列可以是聚合值,也可以是排序值。
开窗函数一般分为两类,聚合开窗函数排序开窗函数

目录

聚合开窗函数

sum开窗函数

count开窗函数

min开窗函数

max开窗函数

avg开窗函数

first_value开窗函数

last_value开窗函数

lag开窗函数

lead开窗函数

NTILE开窗函数

cume_dist开窗函数

排序开窗函数

RANK,DENSE_RANK,ROW_NUMBER开窗函数

percent_rank开窗函数


 首先插入数据:
 

create table score(
name string,
subject string, 
score int) 
row format delimited fields terminated by "\t";

数据:

孙悟空	语文	10
孙悟空	数学	12
孙悟空	英语	15
大海	语文	4
大海	数学	7
大海	英语	11
宋宋	语文	22
宋宋	数学	19
宋宋	英语	3
婷婷	语文	21
婷婷	数学	8
婷婷	英语	23

将数据导入到hive的表格里面:

load data local inpath '/home/hive/score.txt' into table score;

开始测试:

聚合开窗函数

sum开窗函数

-- 不加条件,所有的结果作为窗口
select name ,subject,score,
sum(score) over() as sum1
from score;

-- 以学科作为窗口的所有行
select name ,subject,score,
sum(score) over(partition by subject) as sum
from score;

-- 以学科作为分组,分数排序后,从第一行到当前行(含当前行)的所有行作为窗口
select name ,subject,score,
sum(score) over(partition by subject order by score) as sum
from score;

select name ,subject,score,
sum(score) over() as sum1,
sum(score) over(partition by subject) as sum2,
sum(score) over(partition by subject order by score) as sum3,
-- 由起点到当前行的窗口聚合,和sum3一样
sum(score) over(partition by subject order by score rows between UNBOUNDED PRECEDING and current row) as sum4,
-- 当前行和前面一行的窗口聚合
sum(score) over(partition by subject order by score rows between 1 PRECEDING and current row) as sum5,
-- 当前行和前面一行和后面一行的窗口聚合
sum(score) over(partition by subject order by score rows between 1 PRECEDING AND 1 FOLLOWING) as sum6,
-- 当前和后面所有的行
sum(score) over(partition by subject order by score rows between current row and UNBOUNDED FOLLOWING) as sum7
from score;

rows必须跟在Order by 子句之后,对排序的结果进行限制,使用固定的行数来限制分区中的数据行数量。

小结:

  • OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化。
  • CURRENT ROW:当前行
  • n PRECEDING:往前n行数据
  • n FOLLOWING:往后n行数据
  • UNBOUNDED:起点,UNBOUNDED PRECEDING 表示从前面的起点, UNBOUNDED FOLLOWING表示到后面的终点

注意:n必须为int类型。

count开窗函数

取的是窗口里面的条数

min开窗函数

取的是窗口里面的最小值,同sum函数类似

max开窗函数

取的是窗口里面的最大值,同sum函数类似

avg开窗函数

取的是窗口里面的平均值,同sum函数类似

first_value开窗函数

返回分区里面的第一个值,同sum函数类似

last_value开窗函数

返回分区里面的最后一个值,同sum函数类似

lag开窗函数

LAG(col,n,default_val):往前第n行数据,col是列名,n是往上的行数,当第n行为null的时候取default_val


select name ,subject,score,
 --窗口内 往上取第二个 取不到时赋默认值60
lag(score,2,60) over(partition by subject order by score) as lag1,
 --窗口内 往上取第二个 取不到时赋默认值NULL
lag(score,2) over(partition by subject order by score) as lag2
from score ;

lead开窗函数

LEAD(col,n, default_val):往后第n行数据,col是列名,n是往下的行数,当第n行为null的时候取default_val

select name ,subject,score,
 --窗口内 往下取第二个 取不到时赋默认值60
LEAD(score,2,60) over(partition by subject order by score) as lead1,
 --窗口内 往下取第二个 取不到时赋默认值NULL
LEAD(score,2) over(partition by subject order by score) as lead2
from score ;

NTILE开窗函数

NTILE(n):把有序分区中的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。注意:n必须为int类型。

-- 将结果按分数排序并分成4个组
select name ,subject,score, 
ntile(4) over(order by score) sorted
from score;

cume_dist开窗函数

cume_dist(),计算某个窗口或分区中某个值的累积分布。假定升序排序,则使用以下公式确定累积分布:
小于等于当前值x的行数 / 窗口或partition分区内的总行数。其中,x 等于 order by 子句中指定的列的当前行中的值。

select name ,subject,score,
-- 统计小于等于当前分数的人数占总人数的比例
cume_dist() over(order by score) as cume_dist1,
-- 统计分区内小于等于当前分数的人数占总人数的比例
cume_dist() over(partition by subject order by score) as cume_dist3
from score;

解释第一行:
总行数是12,小于等于第一行的有3,4,7,比例为3/12=0.25;按学科分组后,数学有4个,小于等于7的只有7,所以是0.25

-- 统计大于等于当前分数的人数占总人数的比例
select name ,subject,score,
cume_dist() over(order by score desc) as cume_dist2
from score;

排序开窗函数

RANK,DENSE_RANK,ROW_NUMBER开窗函数

RANK() 排序相同时会重复,总数不会变

DENSE_RANK() 排序相同时会重复,总数会减少

ROW_NUMBER() 会根据顺序计算

在此之前,将数据稍加修改:

select name,subject,score,
rank() over(partition by subject order by score desc) rp,
dense_rank() over(partition by subject order by score desc) drp,
row_number() over(partition by subject order by score desc) rmp
from score;

解释:

看前4行,两个19分,并列第一,rp第三行是3,数据不会少,drp是2,按照顺序排序,总数减少了,最后rmp是按照行数排序。

percent_rank开窗函数

计算给定行的百分比排名。可以用来计算超过了百分之多少的人。(当前行的rank值-1)/(分组内的总行数-1)

select name,subject,score,
row_number() over(partition by subject order by score) as row_number,
percent_rank() over(partition by subject order by score) as percent_rank
from score;

发布了39 篇原创文章 · 获赞 1 · 访问量 4620

猜你喜欢

转载自blog.csdn.net/thetimelyrain/article/details/104194872