Hive Sql的窗口函数
1. count、sum、avg、max、min
以 sum
为例
1 | # 按照 year 来分组,统计每一年的总和 |
通过
explain select ...
来查看语句解析,可以简单理解为,在每一次order by
之后,会执行一次sum
的reduce
过程,也就导致结果计算的是 1 - n 月的累计值
2. rows between
以 sum
为例
1 | # 按照 year 分组,按照 month 排序,计算前3行和后1行的总和 |
- preceding:往前
- following:往后
- current row:当前行
- unbounded:起点
- unbounded preceding:表示从前面的起点
- unbounded following:表示到后面的终点
1 | # 以下两种方式是等效的 |
3. ntile
切片:用于将分组数据按照顺序切分成n片,返回当前切片值;不支持 rows between;如果切片不均匀,默认增加第一个切片的分布(比如有6条数据,分4组,数量依次为2 2 1 1)
1 | # 统计一个月内,val 最多的前 1/n |
4. row_number、rank、dense_rank
- row_number:行号
- rank:排名——结果中可能有空位 eg:1 2 2 4
- dense_rank:排名——结果中无空位 eg:1 2 2 3
5. cume_dist
计算公式:(小于等于当前值的行数 / 分组内的总行数)
1 | # 统计小于等于当前薪水的人占部门内总人数的比例 |
6. percent_rank
计算公式:(分组内当前行的rank值 - 1 / 分组内总行数 - 1)
7. lag(col, n, DEFAULT)
统计窗口内往上第 n 行值
三个参数分别是:列名;往上第 n 行(可选,默认是1);当往上第 n 行为 NULL 的时候,取默认值,如不指定,则为 NULL
8. lead(col, n, DEFAULT)
统计窗口内往下第 n 行值
三个参数分别是:列名;往下第 n 行(可选,默认是1);当往下第 n 行为 NULL 的时候,取默认值,如不指定,则为 NULL
9. first_value(col)
取分组内排序后,取第一个的 col
1 | first_value(col) over(partition by ... order by ...) |
10. last_value(col)
取分组内排序后,截止到当前行,最后一个的 col => 相当于分组排序后,取当前这一行的 col
1 | last_value(col) over(partition by ... order by ...) |
如果不指定 order by,则默认按照记录在文件中的偏移量进行排序,会出现错误的结果
如果要取分组内排序后最后一个 col,可以换成下面的形式
1 first_value(col) over(partition by ... order by ... desc)
11. grouping sets
在一个 group by
查询中,根据不同的维度组合进行聚合,等价于将不同维度的 group by
结果集进行 union all
1 | select year, month, count(1)a, grouping__id |
grouping sets (col1, col2 …) 使用前必须要先写 group by (col1, col2 …), grouping sets 表示在 group by 括号内出现的字段组合的情况,所以 grouping sets 出现的字段肯定是在 group by 中出现过的
grouping__id 表示结果属于哪一个分组集合,只能和 grouping sets 组合着用,单独使用报错。有两个下划线!!!
12. cube
根据 group by 的维度的所有组合进行聚合。
1 | select year, month, count(1)a, grouping__id |
13. rollup
是 cube 的子集,以最左侧的维度为主,从该维度进行层级聚合。
1 | select year, month, count(1)a, grouping__id |