什么是窗口函数?

窗口函数(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的范围:

逻辑语义上说,一个窗口函数的计算“过程”如下:

  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_numfrom ptf_over_testgroup by cdate,pname>,
-- 窗口函数的分区list
partition by pname,
-- 窗口函数的order list
order by cdate,
-- 窗口函数调用
[r:<sum()>, dr:<avg()>]
)

后面会继续介绍hive目前有哪些常用的开窗函数与用法

hive 开窗函数OVER(PARTITION)详解(一)相关推荐

  1. matlab里open命令,matlab函数bwareaopen的详解

    matlab函数_连通区域 1. matlab函数bwareaopen──删除小面积对象 格式:BW2 = bwareaopen(BW,P,conn) 作用:删除二值图像BW中面积小于P的对象,默认情 ...

  2. Hive 中的wordCount、Hive 开窗函数

    Hive 中的wordCount.Hive 开窗函数 目录 Hive 中的wordCount.Hive 开窗函数 Hive 中的wordCount Hive 开窗函数 测试数据 建表语句 1.row_ ...

  3. python decode函数的用法_Oracle DECODE函数的用法详解

    Oracle DECODE函数 使用方法: 1.比较大小 select decode(sign(变量1-变量2),-1,变量1,变量2) from dual; --取较小值 sign()函数根据某个值 ...

  4. Oracle排名函数(Rank)实例详解

    这篇文章主要介绍了Oracle排名函数(Rank)实例详解,需要的朋友可以参考下 --已知:两种排名方式(分区和不分区):使用和不使用partition --两种计算方式(连续,不连续),对应函数:d ...

  5. 利用栈求表达式的值_高一数学月考考点之函数的表达式详解

    函数表达式考点详解,教你轻松学函数 Hello,大家好,这里是摆渡学涯.很高兴在这里跟大家分享知识哦.这次课程我们来为大家讲一下函数表达式相关的考点,教你轻松学函数. 基本概念 什么是函数表达式呢?我 ...

  6. python时间函数报错_python3中datetime库,time库以及pandas中的时间函数区别与详解...

    1介绍datetime库之前 我们先比较下time库和datetime库的区别 先说下time 在 Python 文档里,time是归类在Generic Operating System Servic ...

  7. python命名空间和闭包_Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】...

    本文实例讲述了Python函数基础用法.分享给大家供大家参考,具体如下: 一.什么是命名关键字参数? 格式: 在*后面参数都是命名关键字参数. 特点: 1.约束函数的调用者必须按照Kye=value的 ...

  8. countif和sum套用_if函数嵌套countif、sumif函数实例操作详解 你需要学习了

    excel中if函数嵌套countif函数实例操作详解,需要了解if函数.countif函数.sumif函数字符串引用方式,isblank函数 操作方法 01 用扫描枪连接excel后将自动将货物名称 ...

  9. php函数find的用法,c语言find函数的用法详解

    c语言find函数的用法详解 C语言之find()函数 find函数用于查找数组中的某一个指定元素的位置. 比如:有一个数组[0, 0, 5, 4, 4]: 问:元素5的在什么位置,find函数 返回 ...

最新文章

  1. java用jdbc来rollback,jdbc rollback,该怎么解决
  2. Yii2 restful 分页支持
  3. matlab实现将一个文件夹里面的pcm文件依次合并成一个信号的函数
  4. 【Linux】一步一步学Linux——gdb命令(258)
  5. PowerDesigner导入SQL脚本
  6. 都江堰很美-佩服古人_Crmhf的一天
  7. [XSY4197] Snow(树形DP)
  8. jdbc事务 jta事务_将非事务性资源绑定到JTA事务中的几种模式
  9. 测试工程师需要具备的技能
  10. idea中git的运用
  11. Python入门--集合生成式
  12. Android Native 代码NDK开发学习笔记
  13. 第二个案例实操——创建Bean类
  14. ant vue 设置中文_ant design vue导航菜单与路由配置操作
  15. 《BREW进阶与精通——3G移动增值业务的运营、定制与开发》连载之64---BREW 应用的交叉编译...
  16. 最新VSCode格式化代码不换行
  17. 科普:史上最强单片机
  18. linux 3ds模拟器下载地址,3ds模拟器
  19. 【Python】音节判断
  20. Android Studio 修改 Java 语言版本到 1.8

热门文章

  1. uname -r和uname -a
  2. mit2021计算机竞赛女生,2021全国大学生计算机系统能力大赛操作系统设计赛第一场研讨会隆重举行...
  3. PHP ACCESS-CONTROL-ALLOW-ORIGIN ,设置跨域头
  4. AUC/ROC:面试中80%都会问的知识点
  5. Ubuntu20系统重装/修复
  6. qa问答里的qa什么意思_您应该使用QA Wolf吗?
  7. VT-x/AMD-V 硬件加速在您的系统中不可用。您的 64-位虚拟机将无法检测到 64-位处理器,从而无法启动。
  8. 那个人总有一天会爱你
  9. 杭州seo优化月底工作总结
  10. Android-移动支付 支付宝 微信 银联