(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子句,那么默认就是整个分组内的数据。
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 按顺序编号,相同的值编相同的号,不留空位
对分组内数据进行排序,相同的值也顺序编号:
对分组内数据进行排序,相同的值编号相同,但是占用编号位置,也就是最后编号可能不是连续的:
对分组内数据进行排序,相同的值编号不同,但是不占用编号位置,也就是最后编号是连续的,但是可能会有重复的编号:
数据:
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
NTILE(n) 将分组内数据按照顺序切割成n片。分布不均匀从分片一继续累加。
NTILE 不支持ROWS BETWEEN。
eg:求前1/3、1/4等
小于等于当前值的行数 / 分组内的总行数
eg: 某门课程小于等于当前分数的人占该课程总人数的比例
分组内当前行的RANK值 - 1 / 分组内的总行数 - 1
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 -- 第三行往上取一行,也就是取第二行的值
与LAG相反,用于统计窗口内往下几行
取分组内排序后,截止当前行第一个值
同一个分组内,排序之后,每一行对应的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
取分组内排序后,截止到当前行,最后一个值
相当于倒序排序再取FIRST_VALUE
https://cwiki.apache.org/confluence/display/Hive/Enhanced+Aggregation%2C+Cube%2C+Grouping+and+Rollup
在一个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
将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
从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), ( ))
聚合的编号
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 |