xbb
Hive查询使用中难免遇到各种各样奇奇怪怪的需求或者角度,这个时候合理使用分析窗口函数也许会有很好的效果
前面《我的Hive学习之旅》一文主要讲了row_number(),动态group by还有日期处理之类的问题,稍微涉及了一些窗口函数的东西,但是并没有较为详细地整理一下。今天有时间就整理一下吧~
窗口函数:
窗口函数 | 描述 |
---|---|
lead | 用于统计窗口内往下第n行值。 |
lag | 与lead相反,用于统计窗口内往上第n行值。 |
first_value | 取分组排序后,截止到当前行,第一个值 |
last_value | 取分组排序后,截止到当前行,最后一个值 |
分析函数:
分析函数 | 描述 |
---|---|
RANK | 返回数据项在分区中的排名。排名值序列可能会有间隔 |
DENSE_RANK | 返回数据项在分区中的排名。排名值序列是连续的,不会有间隔 |
PERCENT_RANK | 计算当前行的百分比排名 |
ROW_NUMBER | 确定分区中当前行的序号 |
CUME_DIST | 计算分区中当前行的相对排名 |
NTILE() | 将每个分区的行尽可能均匀地划分为指定数量的分组 |
over子句
- OVER子句可以与标准聚合函数使用(COUNT,SUM,MIN,MAX,AVG)
- OVER可以与一个或多个任何原始数据类型的分区列的PARTITION BY语句使用。
- OVER可以与一个或多个任何原始类型的分区列(排序列)的PARTITION BY(ORDER BY)使用。
- 带有窗口规范的OVER子句。窗口可以在WINDOW子句中单独定义。 窗口规范支持如下格式
1
2
3
4
5
6
7
8
9
(ROWS | RANGE) BETWEEN (UNBOUNDED | [num]) PRECEDING AND ([num] PRECEDING | CURRENT ROW | (UNBOUNDED | [num]) FOLLOWING)
(ROWS | RANGE) BETWEEN CURRENT ROW AND (CURRENT ROW | (UNBOUNDED | [num]) FOLLOWING)
(ROWS | RANGE) BETWEEN [num] FOLLOWING AND (UNBOUNDED | [num]) FOLLOWING
eg:
select dt , count(userid) over day_window as user_num
from table
window day_window as (partition by userid,dt order by diffdays ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW )
当缺少WINDOW子句并指定使用ORDER BY时,窗口规范默认为RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,即从第一行到当前行。
当缺少ORDER BY和WINDOW子句时,窗口规范默认为ROW BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING,即第一行到最后一行。
备注
PRECEDING:表示当前行之前的行
UNBOUNDED PRECEDING: 第一行
num PRECEDING:当前行之前的第num行
CURRENT ROW:当前行
FOLLOWING:当前行之后的行
UNBOUNDED FOLLOWING:最后一行
num FOLLOWING:当前行之后的第num行
range是逻辑窗口,是指定当前行对应值的范围取值,列数不固定,只要行值在范围内,对应列都包含在内
rows是物理窗口,即根据order by 子句排序后,取的前N行及后N行的数据计算(与当前行的值无关,只与排序后的行号相关)
示例代码中便是在带有窗口规范的OVER子句,其窗口便在window子句中单独定义,但如果是分析规范,则不支持。
小提示
在count()等聚合函数中,distinct在hive2.2.0之后才支持order by子句和窗口规范
hive2.1.0之后over子句中支持聚合函数
实战演习
分组取top n
row_number()搭配over子句安排得很明明白白,还有xx_rank()几个函数供使用
1 | select seasonid, episodeid , |
计算累计
引用网上数据1
2
3
4
5
6
7
8
9
10
hive> select * from lxw1234;
OK
cookie1 2015-04-10 1
cookie1 2015-04-11 5
cookie1 2015-04-12 7
cookie1 2015-04-13 3
cookie1 2015-04-14 2
cookie1 2015-04-15 4
cookie1 2015-04-16 4
1 | SELECT cookieid, |
时间序列分析
主要使用lead()等函数