Hive 窗口函数大全

目录

窗口函数概述

窗口序列函数

row_number

dense_rank

窗口边界

滑动窗口

lag 获取上一行数据

lead 获取下一行数据

窗口专用计算函数

sum累加函数

max最大值

min最小值

avg平均值

count累计次数

first_value首行值

last_value末行值

cume_dist分布统计

percent_rank 秩分析函数

nitle数据切片函数


窗口函数概述

over窗口函数说明:

function(arg) over (partition by {partition columns} order by {order columns} desc/asc)

partition columns:当前行中根据指定的列对partition columns列相同值归到一个分区中;

order columns:在相同值的partition columns列分区中,按照order columns列值进行排序,可以指定升序或是降序,默认是升序

function(arg):对应的窗口数据计算函数

窗口序列函数

row_number

在窗口内会对所有数值,输出不同的序号,序号唯一且连续,如:1、2、3、4、5。

row_number() OVER (PARTITION BY COL1 ORDER BY COL2)

表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)。

示例:

SELECT 
ROW_NUMBER() OVER (PARTITION BY province ) AS row_number 
,user_id 
,province 
FROM tmp_cube

结果

row_number    user_id    province
1    137    云南省
2    139    云南省
3    138    云南省
4    136    云南省
5    135    云南省
6    140    云南省
1    133    北京
2    132    北京
3    134    北京
1    124    广东省
2    127    广东省
3    151    广东省
4    123    广东省
5    225    广东省
6    126    广东省

会对相同数值,输出相同的序号,而且下一个序号间断,如:1、1、3、3、5。

示例

SELECT rank() OVER (PARTITION BY province order by part ) AS rank
        ,province
        ,part
FROM    tmp_cube

结果

rank    province    part
1    云南省    01
1    云南省    01
3    云南省    02
3    云南省    02
5    云南省    03
5    云南省    03
1    北京    01
2    北京    02
3    北京    03
1    广东省    01
1    广东省    01
3    广东省    02
3    广东省    02
5    广东省    03
5    广东省    03

dense_rank

会对相同数值,输出相同的序号,但下一个序号不间断,如:1、1、2、2、3。

示例:

SELECT 
dense_rank() OVER (PARTITION BY province order by part ) AS dense_rank 
,province 
,part 
FROM tmp_cube ;

结果

dense_rank    province    part
1    云南省    01
1    云南省    01
2    云南省    02
2    云南省    02
3    云南省    03
3    云南省    03
1    北京    01
2    北京    02
3    北京    03
1    广东省    01
1    广东省    01
2    广东省    02
2    广东省    02
3    广东省    03
3    广东省    03

窗口边界

控制窗口范围,必须配合over窗口的order by排序

参数解释:

n行数

unbounded 不限行数(修饰preceding和following) preceding 在前N行 following 在后N行 current row 当前行

举例说明 :

-- 窗口中整个的范围(over 窗口函数默认是整个窗口范围)

rows between unbounded preceding and unbounded following

-- 从 前无限行 到 当前行

rows between unbounded preceding and current row

-- 从 当前行的前2行 到 当前行

rows between 2 preceding and current row

-- 从 当前行 到 当前行后2行

rows between current row and 2 following

-- 当前行 到 后不限行 rows between current row and unbounded following

滑动窗口

lag 获取上一行数据

LAG(col,n):配合over使用,取窗口范围往前第 n 行数据的值

lead 获取下一行数据

LEAD(col,n):配合over使用,取窗口范围往后第 n 行数据的值

窗口专用计算函数

sum累加函数

实现效果:按照yyyymm统计截至到当前行的sum(num)值;

sum(num) over(partition by user_id,yyyy order by yyyymm asc )
SELECT user_id ,yyyymm ,integral ,sum(integral) over (partition by user_id order by yyyymm) as sum FROM user_totaluser_total ;

结果

user_id    yyyymm    integral    sum
195    202206    20060.0    20060.0
195    202207    23028.0    43088.0
195    202208    20150.0    63238.0
195    202209    20170.0    83408.0
195    202210    20284.0    103692.0
195    202211    20150.0    123842.0
195    202212    20944.0    144786.0
195    202301    \N    144786.0
400    202206    0.0    0.0
400    202207    20384.0    20384.0
400    202208    20150.0    40534.0
400    202209    0.0    40534.0
400    202210    20150.0    60684.0
400    202211    0.0    60684.0
400    202212    0.0    60684.0
400    202301    \N    60684.0
405    202206    0.0    0.0
405    202207    38852.0    38852.0
405    202208    0.0    38852.0
405    202209    13650.0    52502.0
405    202210    25916.0    78418.0
405    202211    0.0    78418.0
405    202212    0.0    78418.0

实现效果:每一个都是的sum(num)值;

sum(num) over(partition by user_id,yyyy )
SELECT 
user_id 
,yyyymm 
,integral 
,sum(integral) over (partition by user_id) as sum 
FROM user_totaluser_total ;

结果

user_id    yyyymm    integral    sum
195    202301    \N    144786.0
195    202206    20060.0    144786.0
195    202207    23028.0    144786.0
195    202208    20150.0    144786.0
195    202209    20170.0    144786.0
195    202210    20284.0    144786.0
195    202211    20150.0    144786.0
195    202212    20944.0    144786.0
400    202301    \N    60684.0
400    202206    0.0    60684.0
400    202207    20384.0    60684.0
400    202208    20150.0    60684.0
400    202209    0.0    60684.0
400    202210    20150.0    60684.0
400    202211    0.0    60684.0
400    202212    0.0    60684.0
405    202207    38852.0    78418.0
405    202206    0.0    78418.0
405    202209    13650.0    78418.0
405    202208    0.0    78418.0
405    202210    25916.0    78418.0
405    202211    0.0    78418.0
405    202212    0.0    78418.0

max最大值

min(expr) OVER([partition_by_clause] order_by_clause [window_clause]);

示例:

SELECT 
user_id 
,yyyymm 
,integral 
,max(integral) over (partition by user_id)
 FROM user_total

结果

user_id    yyyymm    integral    _c3
195    202207    23028.0    23028.0
195    202208    20150.0    23028.0
195    202209    20170.0    23028.0
195    202206    20060.0    23028.0
195    202210    20284.0    23028.0
195    202211    20150.0    23028.0
195    202212    20944.0    23028.0
195    202301    \N    23028.0
400    202209    0.0    20384.0
400    202206    0.0    20384.0
400    202207    20384.0    20384.0
400    202208    20150.0    20384.0
400    202210    20150.0    20384.0
400    202211    0.0    20384.0
400    202212    0.0    20384.0
400    202301    \N    20384.0
405    202206    0.0    38852.0
405    202207    38852.0    38852.0
405    202208    0.0    38852.0
405    202209    13650.0    38852.0
405    202210    25916.0    38852.0
405    202211    0.0    38852.0
405    202212    0.0    38852.0

min最小值

min(expr) OVER([partition_by_clause] order_by_clause [window_clause]);

示例:

SELECT 
user_id 
,yyyymm 
,integral 
,min(integral) over (partition by user_id) 
FROM user_total

结果

user_id    yyyymm    integral    _c3
195    202207    23028.0    23028.0
195    202208    20150.0    23028.0
195    202209    20170.0    23028.0
195    202206    20060.0    23028.0
195    202210    20284.0    23028.0
195    202211    20150.0    23028.0
195    202212    20944.0    23028.0
195    202301    \N    23028.0
400    202209    0.0    20384.0
400    202206    0.0    20384.0
400    202207    20384.0    20384.0
400    202208    20150.0    20384.0
400    202210    20150.0    20384.0
400    202211    0.0    20384.0
400    202212    0.0    20384.0
400    202301    \N    20384.0
405    202206    0.0    38852.0
405    202207    38852.0    38852.0
405    202208    0.0    38852.0
405    202209    13650.0    38852.0
405    202210    25916.0    38852.0
405    202211    0.0    38852.0
405    202212    0.0    38852.0

avg平均值

avg(expr) OVER([partition_by_clause] order_by_clause [window_clause]);

示例:

SELECT 
user_id 
,yyyymm 
,integral 
,avg(integral) over (partition by user_id) 
FROM user_total

结果

user_id    yyyymm    integral    _c3
195    202207    23028.0    20683.714285714286
195    202208    20150.0    20683.714285714286
195    202209    20170.0    20683.714285714286
195    202206    20060.0    20683.714285714286
195    202210    20284.0    20683.714285714286
195    202211    20150.0    20683.714285714286
195    202212    20944.0    20683.714285714286
195    202301    \N    20683.714285714286
400    202209    0.0    8669.142857142857
400    202206    0.0    8669.142857142857
400    202207    20384.0    8669.142857142857
400    202208    20150.0    8669.142857142857
400    202210    20150.0    8669.142857142857
400    202211    0.0    8669.142857142857
400    202212    0.0    8669.142857142857
400    202301    \N    8669.142857142857
405    202206    0.0    11202.57142857143
405    202207    38852.0    11202.57142857143
405    202208    0.0    11202.57142857143
405    202209    13650.0    11202.57142857143
405    202210    25916.0    11202.57142857143
405    202211    0.0    11202.57142857143
405    202212    0.0    11202.57142857143

count累计次数

count(expr) OVER([partition_by_clause] order_by_clause [window_clause]);

示例:

SELECT 
user_id 
,yyyymm 
,integral 
,count(integral) over (partition by user_id) 
FROM user_total

结果

user_id    yyyymm    integral    _c3
195    202207    23028.0    7
195    202208    20150.0    7
195    202209    20170.0    7
195    202206    20060.0    7
195    202210    20284.0    7
195    202211    20150.0    7
195    202212    20944.0    7
195    202301    \N    7
400    202209    0.0    7
400    202206    0.0    7
400    202207    20384.0    7
400    202208    20150.0    7
400    202210    20150.0    7
400    202211    0.0    7
400    202212    0.0    7
400    202301    \N    7
405    202206    0.0    7
405    202207    38852.0    7
405    202208    0.0    7
405    202209    13650.0    7
405    202210    25916.0    7
405    202211    0.0    7
405    202212    0.0    7

first_value首行值

first_value(expr) OVER([partition_by_clause] order_by_clause [window_clause]);

示例:

SELECT 
user_id 
,yyyymm 
,integral 
,first_value(yyyymm) over (partition by user_id order by yyyymm) 
FROM user_total

结果

user_id    yyyymm    integral    _c3
195    202206    20060.0    202206
195    202207    23028.0    202206
195    202208    20150.0    202206
195    202209    20170.0    202206
195    202210    20284.0    202206
195    202211    20150.0    202206
195    202212    20944.0    202206
195    202301    \N    202206
400    202206    0.0    202206
400    202207    20384.0    202206
400    202208    20150.0    202206
400    202209    0.0    202206
400    202210    20150.0    202206
400    202211    0.0    202206
400    202212    0.0    202206
400    202301    \N    202206
405    202206    0.0    202206
405    202207    38852.0    202206
405    202208    0.0    202206
405    202209    13650.0    202206
405    202210    25916.0    202206
405    202211    0.0    202206
405    202212    0.0    202206

last_value末行值

last_value(expr) OVER([partition_by_clause] order_by_clause [window_clause])

示例:

SELECT 
user_id 
,yyyymm 
,integral 
,last_value(yyyymm) over (partition by user_id order by yyyymm) 
FROM user_total

结果

user_id    yyyymm    integral    _c3
195    202206    20060.0    202206
195    202207    23028.0    202207
195    202208    20150.0    202208
195    202209    20170.0    202209
195    202210    20284.0    202210
195    202211    20150.0    202211
195    202212    20944.0    202212
195    202301    \N    202301
400    202206    0.0    202206
400    202207    20384.0    202207
400    202208    20150.0    202208
400    202209    0.0    202209
400    202210    20150.0    202210
400    202211    0.0    202211
400    202212    0.0    202212
400    202301    \N    202301
405    202206    0.0    202206
405    202207    38852.0    202207
405    202208    0.0    202208
405    202209    13650.0    202209
405    202210    25916.0    202210
405    202211    0.0    202211
405    202212    0.0    202212

cume_dist分布统计

如果按升序排列,则统计:小于等于当前值的行数/总行数(number of rows ≤ current row)/(total number ofrows)。

如果是降序排列,则统计:大于等于当前值的行数/总行数

示例:

统计小于等于当前工资的人数占总人数的比例

SELECT 
name
, dept_no
, salary
, cume_dist() OVER (ORDER BY salary) as cume_dist 
FROM data;

结果:

+-------+-------+------+---------+
|name   |dept_no|salary|cume_dist|
+-------+-------+------+---------+
|rose   |2      |4000  |0.125    |
|jack   |2      |5000  |0.375    |
|steven |3      |5000  |0.375    |
|john   |1      |6000  |0.5      |
|jerry  |2      |6600  |0.625    |
|tom    |1      |8000  |0.75     |
|richard|3      |9000  |0.875    |
|mike   |1      |10000 |1.0      |
+-------+-------+------+---------+

根据部门统计小于等于当前工资的人数占部门总人数的比例:

SELECT 
name
, dept_no
, salary
, cume_dist() OVER (PARTITION BY dept_no ORDER BY salary) as cume_dist 
FROM data;

percent_rank 秩分析函数

返回order by列的百分比排名;

计算逻辑:(RANK-1)/(N-1)

即:(rank - 1) / (the number of rows in the window or partition - 1)

select row,value,rank() over() ,PERCENT_RANK() over(partition by 1 order by value) from tablename;

结果:

Row#    Value    Rank    Calculation    PERCENT_RANK
1    15    1    (1-1)/(7-1)    0.0000
2    20    2    (2-1)/(7-1)    0.1666
3    20    2    (2-1)/(7-1)    0.1666
4    20    2    (2-1)/(7-1)    0.1666
5    30    5    (5-1)/(7-1)    0.6666
6    30    5    (5-1)/(7-1)    0.6666
7    40    7    (7-1)/(7-1)    1.0000

nitle数据切片函数

nitle(n),n指将分组内的数据按照order列进行排序切分成n个区,排名序号依次排名为1,2,3,4,5.....,并返回数据切片排名序号;

如,各地区销售额排名:

select 
province
,yyyymm
,gvm
,ntile(5) over(partition by province order by gvm desc) 
from total

结果:

province    yyyymm    gvm    _c3
上海    202210    3416560    1
上海    202206    3050450    1
上海    202207    2974400    2
上海    202209    2611310    2
上海    202208    2353780    3
上海    202205    2002650    3
上海    202204    1556750    4
上海    202211    1510340    5
云南省    202207    3819660    1
云南省    202204    3605550    1
云南省    202210    3493000    2
云南省    202206    3432000    2
云南省    202205    3272100    3
云南省    202209    3123720    3
云南省    202208    3089060    4
云南省    202211    1853150    5

后续可以根据ntile(5)的结果挑选第几切片的数据出来;通常结合n值,用于筛选前20%、10%等数据;

根据上面示例,求各地销售额前20%的数据:

(求前20%,即将数据切分城5份,取第一份数据即可)

select * from 
( select province,yyyymm,gvm,ntile(5) as ntile over(partition by province order by gvm desc) from total ) 
where ntile=1

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值