Hive 窗口函数

文章目录

  • 一、常见聚合操作
      • 1. sum、avg、min、max
  • 二、排序相关的窗口函数
      • 1. row_number
      • 2. rank
      • 3. dense_rank
  • 三、其它窗口函数
      • 1. NTILE
      • 2. cume_dist
      • 3. percent_rank
      • 4. LAG
      • 5. LEAD
      • 6. FIRST_VALUE
      • 7. LAST_VALUE
  • 四、增强聚合操作
      • 1. GROUPING SETS
      • 2. CUBE
      • 3. ROLLUP
      • 4. GROUPING__ID

有ORDER BY子句时对窗口范围的定义

(ROWS | RANGE) BETWEEN (UNBOUNDED | [num]) PRECEDING AND ([num] PRECEDING | CURRENT ROW | (UNBOUNDED | [num]) FOLLOWING)

UNBOUNDED 窗口起点

PRECEDING 基于当前行往前

FOLLOWING 基于当前行往后

CURRENT ROW 当前行

如果不指定这些字句,那么默认表示从起点到当前行

搭配:

ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 表示从起点到当前行

ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING 表示从当前行到最后一行

ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING 表示从当前行往前三行以及往后一行

ROWS BETWEEN 3 PRECEDING AND CURRENT ROW 表示当前行以及往前3行

如果没有ORDER BY子句,那么默认就是整个分组内的数据。

一、常见聚合操作

1. sum、avg、min、max

eg:

cookieId, createtime,pv

cookie1,2015-04-10,1
cookie3,2015-04-10,2
cookie1,2015-04-11,5
cookie2,2015-04-11,7
cookie1,2015-04-12,3
cookie2,2015-04-15,4
cookie3,2015-04-16,4

HQL

SELECT cookieid,createtime,pv,
SUM(pv) OVER(PARTITION BY cookieid ORDER BY createtime) AS pv_sum1,   -- 起点行到当前行
SUM(pv) OVER(PARTITION BY cookieid) AS pv_sum2,  --分组内全部数据
SUM(pv) OVER(PARTITION BY cookieid ORDER BY createtime ROWS BETWEEN 1 PRECEDING
AND CURRENT ROW) AS pv_sum3, -- 往前一行和当前行
FROM cookie_pv order by cookieId, createtime;

结果:

cookieId  createtime  pv  pv_sum1  pv_sum2   pv_sum3
cookie1   2015-04-10  1    1                   9                   1
cookie1   2015-04-11  5    6                   9                   6
cookie1   2015-04-12  3    9                   9                   8
cookie2   2015-04-11  7    7                   11                 7
cookie2   2015-04-15  4    11                 11                 11
cookie3   2015-04-10  2    2                   6                   2
cookie3   2015-04-16  4    6                   6                   6

其它几个和sum的用法一样。

二、排序相关的窗口函数

row_number 按顺序编号,不留空位
rank 按顺序编号,相同的值编相同号,留空位
dense_rank 按顺序编号,相同的值编相同的号,不留空位

1. row_number

对分组内数据进行排序,相同的值也顺序编号:

2. rank

对分组内数据进行排序,相同的值编号相同,但是占用编号位置,也就是最后编号可能不是连续的:

3. dense_rank

对分组内数据进行排序,相同的值编号不同,但是不占用编号位置,也就是最后编号是连续的,但是可能会有重复的编号:

数据:

cookie1,2015-04-10,1
cookie3,2015-04-10,2
cookie1,2015-04-11,5
cookie2,2015-04-11,7
cookie3,2015-04-11,2
cookie1,2015-04-12,3
cookie2,2015-04-15,4
cookie3,2015-04-16,4
SELECT cookieId, createtime, pv,
RANK() OVER(PARTITION BY cookieid ORDER BY pv desc) AS rn1,
DENSE_RANK() OVER(PARTITION BY cookieid ORDER BY pv desc) AS rn2,
ROW_NUMBER() OVER(PARTITION BY cookieid ORDER BY pv DESC) AS rn3
FROM cookie_pv;

结果:

cookieId createtime pv rn1 rn2 rn3
cookie1,2015-04-10,1 1 1 1
cookie1,2015-04-12,3 2 2 2
cookie1,2015-04-11,5 3 3 3
cookie2,2015-04-15,4 1 1 1
cookie2,2015-04-11,7 2 2 2
cookie3,2015-04-10,2 1 1 1
cookie3,2015-04-11,2 1 1 2
cookie3,2015-04-16,4 3 2 3

三、其它窗口函数

1. NTILE

NTILE(n) 将分组内数据按照顺序切割成n片。分布不均匀从分片一继续累加。

NTILE 不支持ROWS BETWEEN。

eg:求前1/3、1/4等

2. cume_dist

小于等于当前值的行数 / 分组内的总行数

eg: 某门课程小于等于当前分数的人占该课程总人数的比例

3. percent_rank

分组内当前行的RANK值 - 1 / 分组内的总行数 - 1

4. LAG

LAG(col,n,DEFAULT) 用于统计窗口内往上第n行值
第一个参数为列名,
第二个参数为往上第n行(可选,默认为1),
第三个参数为默认值(当往上第n行为NULL时候,取默认值,如不指定,则为NULL)

eg:
2015-04-10 10:00:00
2015-04-10 10:00:02
2015-04-10 10:03:04

LAG(createtime,1,'1970-01-01 00:00:00')  当前行往上取1行,默认值为1970-01-01 00:00:00。
1970-01-01 00:00:00    -- 第一行往上取一行,没有,取默认值
2015-04-10 10:00:00    -- 第二行往上取一行,也就是取第一行的值
2015-04-10 10:00:02    -- 第三行往上取一行,也就是取第二行的值

5. LEAD

与LAG相反,用于统计窗口内往下几行

6. FIRST_VALUE

取分组内排序后,截止当前行第一个值

同一个分组内,排序之后,每一行对应的FIRST_VALUE都是该分组的第一个值。

eg:

SELECT cookieId, createtime, url,
ROW_NUMBER() OVER(PARTITION BY cookieid ORDER BY createtime) AS rn,
FIRST_VALUE(url) OVER(PARTITION BY cookieid ORDER BY createtime) AS first1
FROM cookie_url;

cookie1       2015-04-10 10:00:00       url1       1       url1
cookie1       2015-04-10 10:00:02       url2       2       url1
cookie1       2015-04-10 10:03:04       url3       3       url1
cookie2       2015-04-10 10:00:00       url11       1       url11
cookie2       2015-04-10 10:00:02       url22       2       url11
cookie2       2015-04-10 10:03:04       url33       3       url11

7. LAST_VALUE

取分组内排序后,截止到当前行,最后一个值

相当于倒序排序再取FIRST_VALUE

四、增强聚合操作

https://cwiki.apache.org/confluence/display/Hive/Enhanced+Aggregation%2C+Cube%2C+Grouping+and+Rollup

1. GROUPING SETS

在一个group by查询中,根据不同的维度进行聚合,相当于将不同纬度的group by结果集进行union all操作

SELECT a, b, SUM(c) FROM tab1 GROUP BY a, b GROUPING SETS ( (a,b) )     -- a b 两个维度进行聚合
等价于:
SELECT a, b, SUM(c) FROM tab1 GROUP BY a, b


SELECT a, b, SUM( c ) FROM tab1 GROUP BY a, b GROUPING SETS ( (a,b), a)    -- 将a,b整体作为一个维度,以及以a为维度进行聚合
等价于:
SELECT a, b, SUM( c ) FROM tab1 GROUP BY a, b
UNION
SELECT a, null, SUM( c ) FROM tab1 GROUP BY a

2. CUBE

将group by的维度的所有组合进行聚合:

SELECT a, b, SUM(c) FROM tab1 GROUP BY a, b WITH CUBE
相当于
SELECT a, b, SUM(c) FROM tab1 GROUP BY a, b GROUPING SETS ( (a, b), (a), (b), ( ))   四个维度的聚合结果进行union

3. ROLLUP

从group by的第一个维度开始,进行层级聚合

SELECT a, b, SUM(c) FROM tab1 GROUP BY a, b WITH ROLLUP

就是先对a,b维度聚合,然后对a维度聚合,然后()维度聚合

相当于
SELECT a, b, SUM(c) FROM tab1 GROUP BY a, b GROUPING SETS ( (a, b), (a), ( ))

4. GROUPING__ID

聚合的编号

eg:

Column1 (key) Column2 (value)
1 NULL
1 1
2 2
3 3
3 NULL
4 5
SELECT key, value, GROUPING__ID, count(*)
FROM T1
GROUP BY key, value WITH ROLLUP ORDER BY GROUPING__ID;

结果:

Column 1 (key) Column 2 (value) GROUPING__ID count(*)
1 NULL 0 1
1 1 0 1
2 2 0 1
3 NULL 0 1
3 3 0 1
4 5 0 1
1 NULL 1 2
2 NULL 1 1
3 NULL 1 2
4 NULL 1 1
NULL NULL 3 6

你可能感兴趣的:(Hive,hive,窗口函数)