hive开窗函数OVER(PARTITION)详解(⼀)
什么是窗⼝函数?
窗⼝函数(Window Function) 是 SQL2003 标准中定义的⼀项新特性,并在 SQL2011、SQL2016 中⼜加以完善,添加了若⼲处拓展。窗⼝函数不同于我们熟悉的普通函数和聚合函数,它为每⾏数据进⾏⼀次计算:输⼊多⾏(⼀个窗⼝)、返回⼀个值。在报表等分析型查询中,窗⼝函数能优雅地表达某些需求,发挥不可替代的作⽤。
窗⼝函数出现在 SELECT ⼦句的表达式列表中,它最显著的特点就是 OVER 关键字。语法定义如下:
window_function (expression) OVER (
[ PARTITION BY part_list ]
[ ORDER BY order_list ]
[ { ROWS | RANGE } BETWEEN frame_start AND frame_end ]
)
其中包括以下可选项:
PARTITION BY 表⽰将数据先按 part_list 进⾏分区
ORDER BY 表⽰将各个分区内的数据按 order_list 进⾏排序
最后⼀项表⽰ Frame 的定义,即:当前窗⼝包含哪些数据?
ROWS 选择前后⼏⾏,例如 ROWS BETWEEN 3 PRECEDING AND 3 FOLLOWING 表⽰往前 3 ⾏到往后 3 ⾏,⼀共 7 ⾏数据(或⼩于 7 ⾏,如果碰到了边界)
RANGE 选择数据范围,例如 RANGE BETWEEN 3 PRECEDING AND 3 FOLLOWING 表⽰所有值在 [c−3,c+3][c−3,c+3] 这个范围内的⾏,cc 为当前⾏的值
通俗演绎frame的范围:
逻辑语义上说,⼀个窗⼝函数的计算“过程”如下:
groupby是什么函数1. 按窗⼝定义,将所有输⼊数据分区、再排序(如果需要的话)
2. 对每⼀⾏数据,计算它的 Frame 范围
3. 将 Frame 内的⾏集合输⼊窗⼝函数,计算结果填⼊当前⾏
窗⼝函数 VS. 聚合函数
从聚合这个意义上出发,似乎窗⼝函数和 Group By 聚合函数都能做到同样的事情。但是,它们之间的相似点也仅限于此了!这其中的关键区别在于:窗⼝函数仅仅只会将结果附加到当前的结果上,它不会对已有的⾏或列做任何修改。⽽ Group By 的做法完全不同:对于各个Group 它仅仅会保留⼀⾏聚合结果。
有的读者可能会问,加了窗⼝函数之后返回结果的顺序明显发⽣了变化,这不算⼀种修改吗?因为 SQL 及关系代数都是以 multi-set 为基础定义的,结果集本⾝并没有顺序可⾔,ORDER BY 仅仅是最终呈现结果的顺序。
另⼀⽅⾯,从逻辑语义上说,SELECT 语句的各个部分可以看作是按以下顺序“执⾏”的:
注意到窗⼝函数的求值仅仅位于 ORDER BY 之前,⽽位于 SQL 的绝⼤部分之后。这也和窗⼝函数只附加、不修改的语义是呼应的——结果集在此时已经确定好了,再依此计算窗⼝函数。
窗⼝函数的执⾏
窗⼝函数经典的执⾏⽅式分为排序和函数求值这 2 步。
可以看出ptf的执⾏是在group by执⾏完成后,在输出的结果集再进⾏分组排序计算的过程,可以看执⾏计划,测试语句:
explain
select cdate
,pname
,sum(rm) as dp_rm_num
,sum(sum(rm))over(partition by pname
order by cdate range between 1 preceding and current row) as p_rm_num1
,avg(sum(rm))over(partition by pname
order by cdate range between 1 preceding and current row) as p_rm_num2 from ptf_over_test
group by cdate ,pname
执⾏计划过程:
考虑以上代码,在Hive中具体实现主要有两个阶段:
stage-1
计算除窗⼝函数以外所有的其他运算,如:group by,join ,having等。上⾯的代码的第⼀阶段即为:
select cdate,pname,sum(rm) as dp_rm_num
from ptf_over_test
group by cdate,pname
stage-2
将上⼀步的输出作为 WindowingTableFunction 函数的输⼊,计算对应的窗⼝函数值。上⾯代码的第⼀阶段即为:
select cdate,pname,dp_rm_num,p_rm_num1,p_rm_num2 from
WindowingTableFunction(
-- 上⼀阶段的输出
<select cdate,pname,sum(rm) as dp_rm_num
from ptf_over_test
group by cdate,pname>,
-- 窗⼝函数的分区list
partition by pname,
-- 窗⼝函数的order list
order by cdate,
-- 窗⼝函数调⽤
[r:<sum()>, dr:<avg()>]
)
后⾯会继续介绍hive⽬前有哪些常⽤的开窗函数与⽤法
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论