hive-窗口函数

1 窗口函数语法

分析函数/专用窗口函数 over(partition by 列名 order by 列名 rows between 开始位置 and
结束位置)

常用的分析函数

常用的分析函数:sum()、max()、min()、avg()、count()

常用的专用窗口函数

专用窗口函数:row_number()、rank()、dense_rank()

窗口函数

窗口函数的3个组成部分可以单独使用,也可以混合使用,也可以全部不用

over(partition by 列名 order by 列名 rows between 开始位置 and 结束位置)

partition by

对指定的字段进行分组,后续都会以组为单位,把每个分组单独作为一个窗口进行统计分析操作。

案例 01:对窗口中的数据求和,并把求和结果分别分发到对应窗口的每一条数据中

with temp as(
select 'A' as col1,1 as col2
union all 
select 'A' as col1,1 as col2
union all 
select 'B' as col1,1 as col2
)select
col1
,sum(col2) over(partition by col1) as '对窗口中的数据求和'
from temp
输出结果:
col     对窗口中的数据求和
A       2
A       2
B       1

案例 02:对整体数据求和,并把求和结果分发到每一条数据中

with temp as(
select 'A' as col1,1 as col2
union all 
select 'A' as col1,1 as col2
union all 
select 'B' as col1,1 as col2
)select
col1
,sum(col2) over() as '对整体数据求和'
from temp
输出结果:
col     对整体数据求和
A       3
A       3
B       3

order by

order by 与 partition by 连用的时候,可以对各个分组内的数据,按照指定的字段进行排序。如果没有 partition by 指定分组字段,那么会对全局的数据进行排序。

案例 01:对数据进行全局排序

with temp as(
select 'A' as col1,1 as col2
union all 
select 'C' as col1,1 as col2
union all 
select 'B' as col1,1 as col2
)select col1,row_number() over(order by col1 desc) as 排序 from temp
输出结果:
col1     排序 
C        1
C        2
B        3
A        4

案例 02:当排序的维度不存在重复的情况下,即 order by 指定的字段,使用 order by + 分析函数 sum(),可以产生求整体累计数的效果。

with temp_01 as(
select 'A' as col1,1 as col2
union all 
select 'D' as col1,1 as col2
union all 
select 'C' as col1,1 as col2
union all 
select 'B' as col1,1 as col2
)select col1,sum(col2) over(order by col1) as 求累计 from temp_01
输出结果:
col1    求累计
A       1
B       2
C       3
D       4

但是当 order by 指定的字段,数据存在重复的时候,会在不重复的数据中产生累计效果,重复的数据中,会把整体的累计结果分发到每条重复的数据中。

with temp_02 as(
select 'A' as col1,1 as col2
union all 
select 'C' as col1,1 as col2
union all 
select 'C' as col1,1 as col2
union all 
select 'B' as col1,1 as col2
)select col1,sum(col2) over(order by col1) as 求累计 from temp_02
输出结果:
col1    求累计
A       1
B       2
C       4
C       4

案例 03:当排序的维度不存在重复的情况下,即 order by 指定的字段,parition by 与 order by 连用,并使用分析函数 sum() ,可以产生求窗口中累计数的效果。

with temp_01 as(
select 'A' as col1,'b' as col2,1 as col3
union all 
select 'A' as col1,'a' as col2,1 as col3
union all 
select 'C' as col1,'a' as col2,1 as col3
union all 
select 'C' as col1,'b' as col2,1 as col3
)select col1,sum(col3) over(partition by col1 order by col1,col2) as 求累计 from temp_01
输出结果:
col1     求累计
A        1
A        2
C        1
C        2

但是当 order by 指定的字段组合,数据存在重复的时候,会在不重复的数据中产生累计效果,而重复的数据中,也是会把整体的累计结果分发到每条重复的数据中,如下,用 col1 和 col2 排序。

with temp_02 as(
select 'A' as col1,'b' as col2,1 as col3
union all 
select 'A' as col1,'a' as col2,1 as col3
union all 
select 'C' as col1,'a' as col2,1 as col3
union all 
select 'C' as col1,'a' as col2,1 as col3
)select col1,sum(col3) over(partition by col1 order by col1,col2) as 求累计 from temp_02
输出结果:
col1     求累计
A        1
A        2
C        2
C        2

rows between 开始位置 and 结束位置

rows between 是用来划分窗口中,函数发挥作用的数据范围。我们用如下例子加深 rows between 的理解。
在这里插入图片描述

在A分组中,计算第2行,第2列的值的时候,会从窗口起点(第2行,第2列),计算到当前行(第2行,第2列)。结果是1。
在A分组中,计算第3行,第2列的值的时候,会从窗口起点(第2行,第2列),计算到当前行(第3行,第2列)。结果是2。

rows between 常用的参数如下:

① n preceding:往前

② n following:往后

③ current row:当前行

④ unbounded:起点(一般结合preceding,following使用)

a. unbounded preceding:表示该窗口最前面的行(起点) b. unbounded
following:表示该窗口最后面的行(终点)

使用例子如下:

rows between unbounded preceding and current row(表示从起点到当前行的数据进行) rows
between current row and unbounded following(表示当前行到终点的数据进行) rows
between unbounded preceding and unbounded following (表示起点到终点的数据) rows
between 1 preceding and 1 following(表示往前1行到往后1行的数据) rows between 1
preceding and current row(表示往前1行到当前行)

rows between unbounded preceding and current row与 partition by 、order by 连用,可以产生对窗口中的数据求累计数的效果。

with temp as(
select 'A' as col1,1 as col2
union all 
select 'A' as col1,1 as col2
union all 
select 'B' as col1,1 as col2
)select
col1
,sum(col2) over(partition by col1 order by col2 desc rows between unbounded preceding and current row) as '对窗口中的数据求和'
from temp
输出结果:
col1     对窗口中的数据求和
A        1
A        2
B        1
  1. 排序窗口函数
    2.1 排序并产生自增编号,自增编号不重复且连续
    我们可以使用函数:row_number() over()

数据样例:

col1                             ranks
a            1
b              2
b              3
b              4
c              5
d              6具体语法如下:> row_number() over(partition by 列名 order by 列名 rows between 开始位置 and
> 结束位置)案例如下:>with temp as(
select 'a' as col1
union all 
select 'b' as col1
union all 
select 'b' as col1
union all 
select 'b' as col1
union all 
select 'c' as col1
union all 
select 'd' as col1
)
>
>select col1,row_number() over(order by col1) as ranks from temp
输出结果:
col1     rank
a        1
b        2
b        3
b        4
c        5
d        6

2.2 排序并产生自增编号,自增编号会重复且不连续
我们可以使用函数:rank() over()

数据样例:

col1     ranks
a        1
b        2
b        2
b        2
c        5
d        6

具体语法如下:

rank() over(partition by 列名 order by 列名 rows between 开始位置 and 结束位置)

案例如下:

with temp as(
select 'a' as col1
union all 
select 'b' as col1
union all 
select 'b' as col1
union all 
select 'b' as col1
union all 
select 'c' as col1
union all 
select 'd' as col1
)select col1,rank() over(order by col1) as ranks from temp
输出结果:
col1     rank
a        1
b        2
b        2
b        2
c        5
d        6

2.3 排序并产生自增编号,自增编号会重复且连续
我们可以使用函数:dense_rank() over()

数据样例:

col1     ranks
a        1
b        2
b        2
b        2
c        3
d        4

具体语法如下:

dense_rank() over(partition by 列名 order by 列名 rows between 开始位置 and
结束位置)

案例如下:

with temp as(
select 'a' as col1
union all 
select 'b' as col1
union all 
select 'b' as col1
union all 
select 'b' as col1
union all 
select 'c' as col1
union all 
select 'd' as col1
)select col1,dense_rank() over(order by col1) as ranks from temp	
输出结果:
col1     ranks
a        1
b        2
b        2
b        2
c        3
d        4

聚合窗口函数

3.1 求窗口中的累计值
我们可以使用:sum() over()

with temp as(
select 'A' as col1,1 as col2
union all 
select 'A' as col1,1 as col2
union all
select 'A' as col1,1 as col2
union all 
select 'B' as col1,1 as col2
union all 
select 'B' as col1,1 as col2
)select
col1
,sum(col2) over(partition by col1 order by col2 desc rows between unbounded preceding and current row) as '对窗口中的数据求和'
from temp
输出结果:
col1     对窗口中的数据求和
A        1
A        2
A        3
B        1
B        1

3.2 求窗口中 3 天的平均价格
我们可以使用 avg() over()

with temp as(
select 'A' as col1,'2022-11-01' as date_time,50 as price
union all 
select 'A' as col1,'2022-11-02' as date_time,60 as price
union all 
select 'A' as col1,'2022-11-03' as date_time,45 as price
union all 
select 'A' as col1,'2022-11-04' as date_time,70 as price
union all 
select 'A' as col1,'2022-11-05' as date_time,40 as price
union all 
select 'A' as col1,'2022-11-06' as date_time,40 as price
union all 
select 'B' as col1,'2022-11-01' as date_time,40 as price
union all 
select 'B' as col1,'2022-11-02' as date_time,30 as price
union all 
select 'B' as col1,'2022-11-03' as date_time,50 as price
union all 
select 'B' as col1,'2022-11-04' as date_time,50 as price
)select
col1
,date_time
,price
,avg(price) over(partition by col1 order by date_time rows between 2 preceding and current row) as '3天的平均价格'
from temp输出结果:
col1      date_time        price      3天的平均价格
A         2022-11-01       50         50
A         2022-11-02       60         55
A         2022-11-03       45         51.666666666666664
A         2022-11-04       70         58.333333333333336
A         2022-11-05       40         51.666666666666664
A         2022-11-06       40         50
B         2022-11-01       40         40
B         2022-11-02       30         35
B         2022-11-03       50         40
B         2022-11-01       50         43.333333333333336

3.3 求分组中的最大值/最小值

with temp_01 as(
select 'A' as col1,10 as col2
union all 
select 'C' as col1,10 as col2
union all 
select 'C' as col1,20 as col2
union all 
select 'A' as col1,20 as col2
union all
select 'A' as col1,20 as col2
)select
col1
,col2
,max(col2) over(partition by col1) as 窗口中的最大值
,min(col2) over(partition by col1) as 窗口中的最小值
from temp_01输出结果:
col1     col2     窗口中的最大值     窗口中的最小值
A        10       20                 10
A        20       20                 10
A        20       20                 10
C        10       20                 10
C        20       20                 10

3.4 求分组中的总记录数

with temp_01 as(
select 'A' as col1,'a' as col2
union all 
select 'C' as col1,'a' as col2
union all 
select 'C' as col1,'a' as col2
union all 
select 'A' as col1,'b' as col2
union all
select 'A' as col1,'b' as col2
)select
col1
,col2
,count(col2) over(partition by col1) as 分组中的记录数
from temp_01输出结果:
col1     col2     分组中的记录数
A        a        3
A        b        3
A        b        3
C        a        2
C        a        2
  1. 位移窗口函数
    4.1 获取分组中往前 n 行的值
    基础语法:

lead(field,n,default_value) over()

语法解析:

  1. field 是指定的列名

  2. n 是往前的行数

  3. 行往前导致的,最后的 n 行值为 null,可以用 default_value 代替。

使用案例:

with temp_01 as(
select 'A' as col1,'2022-12-01' as date_time
union all 
select 'C' as col1,'2022-12-01' as date_time
union all 
select 'C' as col1,'2022-12-02' as date_time
union all 
select 'A' as col1,'2022-12-02' as date_time
union all
select 'A' as col1,'2022-12-03' as date_time
)select
col1
,date_time
,lead(date_time,1,'2022-12-30') over(partition by col1 order by date_time) as 往前n行的值 
from temp_01输出结果:
col1     date_time     往前n行的值
A        2022-12-01    2022-12-02
A        2022-12-02    2022-12-03
A        2022-12-03    2022-12-30
C        2022-12-01    2022-12-02
C        2022-12-02    2022-12-30

4.2 获取分组中往后 n 行的值
基础语法:

lag(field,n, default_value) over()

语法解析:

  1. field 是指定的列名

  2. n 是往前的行数

  3. 行往后导致的,前面的 n 行值为 null,可以用 default_value 代替。

使用案例:

with temp_01 as(
select 'A' as col1,'2022-12-01' as date_time
union all 
select 'C' as col1,'2022-12-01' as date_time
union all 
select 'C' as col1,'2022-12-02' as date_time
union all 
select 'A' as col1,'2022-12-02' as date_time
union all
select 'A' as col1,'2022-12-03' as date_time
)select
col1
,date_time
,lag(date_time,1,'2022-12-30') over(partition by col1 order by date_time) as 往前n行的值 
from temp_01输出结果:
col1      date_time     往前n行的值
A         2022-12-01    2022-12-30
A         2022-12-02    2022-12-01
A         2022-12-03    2022-12-02
C         2022-12-01    2022-12-30
C         2022-12-02    2022-12-01

极值窗口函数

5.1 获取分组内第一行的值
我们可以使用 first_value(col,true/false) over(),作用是:取分组内排序后,截止到当前行,第一个值。

注意:

当第二个参数为 true 的时候,会跳过空值 当 over() 中不指定排序的时候,会默认使用表中数据的原排序。
案例:将每行数据换成当前窗口指定字段的第一个值

with temp_01 as(
select 'A' as col1,'b' as col2
union all 
select 'C' as col1,'a' as col2
union all 
select 'C' as col1,'b' as col2
union all 
select 'A' as col1,'a' as col2
union all
select 'A' as col1,'b' as col2
)select
col1
,first_value(col2) over(partition by col1 order by col2) as 第一个值 
from temp_01
输出结果:
col1     第一个值
A        a
A        a
A        a
C        a 
C        a
select
col1
,first_value(col2) over(partition by col1) as 第一个值 
from temp_01
输出结果:
col1     第一个值
A        b
A        b
A        b
C        a
C        a

5.2 获取分组内最后一行的值
我们可以使用 last_value(col,true/false) over(),作用是:取分组内排序后,截止到当前行,最后一个值。所以,如果使用 order by 排序的时候,想要取最后一个值,需要与 rows between unbounded preceding and unbounded following 连用。

注意:

当第二个参数为 true 的时候,会跳过空值 当 over() 中不指定排序的时候,会默认使用表中数据的原排序。 当 over()
中指定排序的时候,要与 rows between unbounded preceding and unbounded following
连用

with temp_01 as(
select 'A' as col1,'b' as col2
union all 
select 'C' as col1,'a' as col2
union all 
select 'C' as col1,'b' as col2
union all 
select 'A' as col1,'a' as col2
union all
select 'A' as col1,'b' as col2
)select
col1
,last_value(col2) over(partition by col1 order by col2 rows between unbounded preceding and unbounded following) as 第一个值 
from temp_01输出结果:
col1       第一个值
A          b
A          b
A          b
C          b
C          b

相信大家都发现了,在本案例中,我们使用 order by 的时候与 rows between unbounded preceding and unbounded following 连用了,这是需要注意的一个点,如果不连用,将会产生以下效果:

with temp_01 as(
select 'A' as col1,'b' as col2
union all 
select 'C' as col1,'a' as col2
union all 
select 'C' as col1,'b' as col2
union all 
select 'A' as col1,'a' as col2
union all
select 'A' as col1,'b' as col2
)select
col1
,last_value(col2) over(partition by col1 order by col2) as 第一个值 
from temp_01输出结果:
col1      第一个值
A         a
A         b
A         b
C         a
C         b
  1. 分箱窗口函数
    ntile() over() 分箱窗口函数,用于将分组数据按照顺序切分成 n 片,返回当前切片值,如果切片不均匀,默认增加到第一个切片中。

案例:查询成绩前 20% 的人。

with temp as(
select 'A' as col1,90 as grade
union all 
select 'B' as col1,80 as grade
union all
select 'C' as col1,82 as grade
union all
select 'D' as col1,99 as grade
union all 
select 'E' as col1,100 as grade
union all 
select 'F' as col1,92 as grade
union all
select 'G' as col1,93 as grade
union all
select 'H' as col1,85 as grade
union all
select 'I' as col1,95 as grade
union all
select 'J' as col1,70 as grade
)select 
col1
,grade
from(selectcol1,grade,ntile(5) over(order by grade desc) as levelfrom temp)t1
where t1.level = 1输出结果:
col1     grade
E        100
D        99

转载:https://zhuanlan.zhihu.com/p/587440793

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/215253.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Qt】Qt获取操作系统和网络信息示例

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍Qt获取操作系统和网络信息示例。 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更…

没有明确的报错信息,阿里云国际版Windows服务器无法远程连接

在远程连接失败时,如果您没有收到系统返回的报错信息,并且ECS实例是运行中的状态,然后再根据以下步骤进行排查: 步骤一:使用阿里云Workbench工具测试远程登录 步骤二:检查是否有收到黑洞通知 步骤三&…

Hbase2.5.5分布式部署安装记录

文章目录 1 环境准备1.1 节点部署情况1.2 安装说明 2 Hbase安装过程Step1:Step2:Step3:Step4: 3 Web UI检查状态并测试3.1 Web UI3.2 创建测试命名空间 1 环境准备 1.1 节点部署情况 Hadoop11:Hadoop3.1.4 、 zookeeper3.4.6、jdk8 Hadoop1…

Unity之OpenXR+XR Interaction Toolkit接入微软VR设备Windows Mixed Reality

前言 Windows Mixed Reality 是 Microsoft 用于增强和虚拟现实体验的VR设备,如下图所示: 在国内,它的使用率很低,一把都是国外使用,所以适配起来是相当费劲。 这台VR设备只能用于串流Windows,启动后,会自动连接Window的Mixed Reality程序,然后打开微软的增强现实门户…

云原生的 CI/CD 框架tekton - Trigger(二)

上一篇为大家详细介绍了tekton - pipeline,由于里面涉及到的概念比较多,因此需要好好消化下。同样,今天在特别为大家分享下tekton - Trigger以及案例演示,希望可以给大家提供一种思路哈。 文章目录 1. Tekton Trigger2. 工作流程3…

在线学习平台-课程分页、用户管理、教师查询

在线学习平台------手把手教程👈 用户管理 添加功能增强 新增属性 若依里的用户模块(SysUser)是没有课程这一属性的,要实现我们自己的课程分页查询功能 这个位置传入的实体类SysUser要加上classId,记得加上get、set方法 更改sql语句 ctrl 鼠标左键不断点进去…

C++联合体union

联合体 将多个类型合并到一起省空间 枚举与联合一起使用 匿名联合 类似于无作用域 C11联合体定义非内建类型 C11 引入了能够在联合体中使用非内建类型的能力,这些类型包括具有自定义构造函数、析构函数、拷贝构造函数和拷贝赋值运算符的类。 关键特性…

如何将用户有过行为的item用list形式记录下来,另外如何计算list里的个数

导语: 最近做项目,发现有些语法想一想是知道,但实际操作起来跟想的情况不一样哈哈。不是遇见bug就是输出的结果不是自己想要的,CSDN跟知乎找了很多没怎么解决,后面多摸索多实操终于解决! test_data[item_…

JAVA实操经验

零: 按照需要,可以使用需要某个类下(主要是java提供的)的方法来实现某个功能。(主要是用在不同类下的方法会进行重写功能不同) 方法和构造方法不同:方法是方法,构造方法是构造器&a…

开箱即用的C++决策树简单实现

一个数据结构期末作业(有兴趣用的话可以高抬贵手star下⭐~)GitHub - mcxiaoxiao/c-Decision-tree: 决策树c简单实现 🌳 c-Decision-tree 附大作业/课设参考文档.doc 🌳 c-Decision-tree Introduction 🙌 c-Decision…

【S32DS RTD实战】-1.3-S32K3工程生成S19,BIN,Hex文件,以及Post-build steps的妙用

目录 1 方法一:逐个生成Motorola S-record(s19,srec…),Intel HEX,Bin文件 1.1 生成Motorola S-record(s19,srec…)文件 1.2 生成Intel HEX文件 1.3 生成Bin文件 2 …

redis(设置密码)配置文件详细

1.设置账号密码端口 config set requirepass 123456 设置密码为123456 config get requirepass 查看账号密码 auth 123456 登入的时候输入这个确定账号密码 1. 首先连接到Redis服务器: redis-cli 2. 然后使用CONFIG SET命令设置requirepass参数并指定密码: CONFIG SET requi…

Android Audio实战——音频链路分析(二十五)

在 Android 系统的开发过程当中,音频异常问题通常有如下几类:无声、调节不了声音、爆音、声音卡顿和声音效果异常(忽大忽小,低音缺失等)等。尤其声音效果这部分问题通常从日志上信息量较少,相对难定位根因。想要分析此类问题,便需要对声音传输链路有一定的了解,能够在链…

SpringData JPA 搭建 xml的 配置方式

1.导入版本管理依赖 到父项目里 <dependencyManagement><dependencies><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-bom</artifactId><version>2021.1.10</version><scope>…

uniapp实战 —— 弹出层 uni-popup (含vue3子组件调父组件的方法)

效果预览 弹出的内容 src\pages\goods\components\ServicePanel.vue <script setup lang"ts"> // 子组件调父组件的方法 const emit defineEmits<{(event: close): void }>() </script><template><view class"service-panel"…

XCube——用于超高分辨率 3D 形状和场景的生成模型!

他们的方法在稀疏体素网格的层次结构上训练潜在扩散模型的层次结构。他们在稀疏结构 VAE 的潜在空间上进行扩散&#xff0c;它为层次结构的每个级别学习紧凑的潜在表示。 XCube 是稀疏体素层次上的分层潜在扩散模型&#xff0c;即从粗到细的 3D 稀疏体素网格序列&#xff0c;使…

视频集中存储/智能分析融合云平台EasyCVR平台接入rtsp,突然断流是什么原因?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

RabbitMQ反序列化未经授权的类异常解决方案

配置好生产者消费者后&#xff0c;消费者项目启动后出现如下异常&#xff1a; Caused by: java.lang.SecurityException: Attempt to deserialize unauthorized 这是反序列化未经授权的类&#xff0c;解决办法是设置信任所有消息发起者&#xff0c;可以将环境变量&#xff1a; …

【算法优选】 动态规划之路径问题——贰

文章目录 &#x1f38b;前言&#x1f332;[下降最小路径和](https://leetcode.cn/problems/minimum-path-sum/)&#x1f6a9;题目描述&#x1f6a9;算法思路&#xff1a;&#x1f6a9;代码实现 &#x1f38d;[最小路径和](https://leetcode.cn/problems/minimum-path-sum/)&…

搜集怎么绘制三维曲线和曲面?

1、针对函数对象是单一变量、两个函数的情况。用plot3函数&#xff1b;&#xff08;三维曲线&#xff09; 看一下matlab官方的例子&#xff1a; t 0:pi/50:10*pi; st sin(t); ct cos(t); plot3(st,ct,t) 绘制出来的曲线&#xff1a; 几个比较关键的点&#xff1a; &…