【面试必问】窗口函数全解-HIVE

简介: 【面试必问】窗口函数全解-HIVE

这是我的第30篇原创

其实很讨厌有人问窗口函数,因为窗口函数解决的是我在刚开始工作时遇到的问题。因为是BI工程师出身,从业开始就在做各种排名、同比、环比、帕累托占比、当前最大等各种乱七八糟的表格需求。


什么是窗口函数?网上很多数据都写的乱七八糟,搞得好像你越看不懂就显得他越厉害一样。来吧,保证你只要会select,就能看的懂这篇文章!

OK,Let's GO!


什么是窗口函数?

一句话解释:

窗口是什么?窗口就是在完整的房子边上开一个大洞,用来通风、观察。

窗口函数是什么?窗口函数就是在完整的表上开一个大洞,在大洞中再开若干小洞,用来观察、计算表中的数据的一类函数。

窗口函数又叫OLAP(OnlineAnalytical Processing)函数,其实就是用来画表格的函数。特别擅长处理各种分组排序、同比环比、累计占比、TOP等复杂分析操作。


窗口函数能做什么?

你现在收到一个人事部门的需求:统计每个业务员的每个月的业绩,包括当月业绩、当年最大单月业绩、当年累计业绩。简单设计了一张表,表头如下:

你迅速整理了思路,准备这么做:

1、先把每个业务员每个月的业绩统计出来,存成中间表A表

2、然后根据中间表,统计出当月业绩、当年累计业绩、当年最大单月业绩。


但是你在做的时候发现,当年累计和当年最大单月业绩,每个月的计算范围不一样,截止时间应该是1月到当前月份。所以你想了两种方法:

  • 写一个简单脚本,每次都max和sum,但是执行12遍(月份为参数),当月的数据用join、子查询或者其他方式并进去。

select 月份,业务员, max(当月业绩,sum(当月业绩) from a where a.月份<=‘2月’

  • 写一个比较复杂的脚本,用中间表A表join自己,然后join的时候设置月份要小于当前月份,但是得捋很多遍的逻辑,一不小心就会出错。代码我写了一下,头大,如果写错了,私信我,给你发红包~~~

select aa.b业务员, aa.b月份, aa.b当月业绩, sum(aa.a当月业绩) as 当年累计业绩, max(aa.a当月业绩) as 当年最大单月业绩 from

(select a.业务员 as a业务员, a.月份 as a月份, a.当月业绩 as a当月业绩,b.业务员 as b业务员, b.月份 as b月份, b.当月业绩 as b当月业绩

from 中间表 A join 中间表 B on a.业务员 = b.业务员) aa

where aa.a月份 <= aa.b月份 group by aa.b业务员, aa.b月份, aa.b当月业绩 order by aa.b业务员, aa.b月份;


你们知道我想说什么。上述的sql都是通过聚合函数(avg、sum、max、min等)+子查询+join来实现的。

实际上大部分数据库除了聚合函数之外,还提供了窗口函数、分析函数、排序函数等各种函数。这些函数结合起来非常好用。

刚才的需求为例,实际上这个需求理解起来非常简单,就是按照每个业务员进行分组,然后在每个分组中,取每个月份的当前值、最大值和累计值。


那么我们只需要一个sql就能搞定三个指标的计算

select 业务员,月份,商品金额,

sum(商品金额) over (partition by 业务员 order by 月份 asc rows between unbounded preceding and current row) as 当年累计业绩,

max(商品金额) over (partition by 业务员 order by 月份 asc rows between unbounded preceding and current row) as 当年最大单月业绩

from 原始业绩表

解释一下:

partition就是对每个业务员的数据单独分组,然后进行内部计算;

order by就是你计算的时候是按什么顺序进行计算的;

rows between ... and 就是在计算的时候,窗口的区域是从哪里到哪里

unbounded preceding就是当前分组第一行,

current row就是当前行

组合起来就是:

sum(商品金额) over (partition by 业务员 order by 月份 asc rows between unbounded preceding and current row) as 当年累计业绩,

按照业务员进行分组,月份从小到大排序之后,累计贾总第一个月到当前月的商品金额。翻译成人话就是计算每个业务员当年累计业绩。over。


这就是窗口函数的作用。每个业务员的每份数据都开一个窗口,在这个窗口中单独计算。

partition就是以业务员进行开窗(分区),between 和 and就是你在计算这个数值的时候,是否有区域条件(窗口中的窗口),and 之前的“unbounded preceding”就是第一条数据开始,and 之后的“current row”就是当前这条数据。


同样,你可以一条语句算出帕累托值(累计占比),不用加辅助字段,不用中间表,不用给自己关联自己,一个窗口函数就搞定。下面两个语句的结果一除就好,语句太长,所以只是计算出来两个字段,没有除出结果。

sum(商品金额) over (partition by 业务员 order by 月份 asc rows between unbounded preceding and current row) as 当年累计到当月业绩,

sum(商品金额) over (partition by 业务员 order by 月份 asc rows between unbounded preceding and unbounded following) as 全年累计业绩,


同样,同比环比也都可以用类似函数直接搞定。怎么样?厉害吧?


窗口函数全解

窗口函数基本语法:

操作函数(窗口、聚合、排序等)+窗口函数基本内容【 over + partition分区+排序+窗口内区域


  • 窗口操作函数:

1.LEAD(字段,位移数,默认值) :向下位移N行取值

2.LAG(字段,位移数,默认值) :向上位移N行取值

3.FIRST_VALUE:当前分组第一个值

4.LAST_VALUE:当前分组最后一个值

示例:

,lead(当月业绩,1,-9999) over (partition by 业务员 order by 月份) as 下月业绩

,lag(当月业绩,1,-9999) over (partition by 业务员 order by 月份) as 上月业绩

窗口函数基本内容:

over (partition by 字段 order by 字段 asc rows between ** and**  )

  • 聚合函数

这个就不用解释了吧?聚合就是“多行变一行”的操作。有:

sum、max、min、avg、count

与窗口函数一起用的示例其实上面已经写了几个了,这里就不再复述了

  • 排序函数(分析函数)

1.ROW_NUMBER:从1开始,按照顺序编号

2.RANK:生成排名,相同得分排名相同,并留空位。

3.DENSE_RANK:生成排名,相同得分排名相同,并不留空位。

4.CUME_DIST:小于等于当前值的行数/分组内总行数

5.PERCENT_RANK:分组内当前排名占总排名的百分比

6.NTILE:分桶,将分组内的数据均匀分N桶

示例:

,ROW_NUMBER() over (partition by 业务员 order by 当月业绩) as ROW_NUMBER1

,RANK() over (partition by 业务员 order by 当月业绩) as RANK1

,DENSE_RANK() over (partition by 业务员 order by 当月业绩) as DENSE_RANK1

,CUME_DIST() over (partition by 业务员 order by 当月业绩) as CUME_DIST1

这些在计算绩效的时候非常好用,尤其是业务员的业绩计算,其中有大量排名,业务员之间全国排名、大区排名、省级排名什么的,应用场景非常多。

至于窗口内排名占比和分桶,比较少用,可以存着备用。


写累了...洗洗睡了,希望能帮到你,晚安,好梦~~~

相关文章
|
9月前
|
SQL 存储 分布式计算
Hive数据仓库设计与优化策略:面试经验与必备知识点解析
本文深入探讨了Hive数据仓库设计原则(分区、分桶、存储格式选择)与优化策略(SQL优化、内置优化器、统计信息、配置参数调整),并分享了面试经验及常见问题,如Hive与RDBMS的区别、实际项目应用和与其他组件的集成。通过代码样例,帮助读者掌握Hive核心技术,为面试做好充分准备。
760 0
|
SQL 分布式计算 Hadoop
Hadoop Hive面试连环炮 1
Hadoop Hive面试连环炮
81 0
|
9月前
|
SQL 存储 分布式计算
Hive精选10道面试题
Hive精选10道面试题
358 3
Hive精选10道面试题
|
9月前
|
SQL Java HIVE
Hive高频面试题之UDTF实现多行输出
Hive高频面试题之UDTF实现多行输出
87 0
|
9月前
|
SQL 存储 大数据
大数据开发岗面试30天冲刺 - 日积月累,每日五题【Day01】——Hive1
大数据开发岗面试30天冲刺 - 日积月累,每日五题【Day01】——Hive1
100 0
|
SQL 分布式计算 Hadoop
Hadoop Hive面试连环炮 2
Hadoop Hive面试连环炮
61 0
|
SQL 移动开发 并行计算
不需要编写代码,也能成为Hive SQL面试高手?ChatGPT告诉你...
当你面对 Hive SQL 面试时,不仅需要掌握 SQL 语言的基本知识,还需要熟练掌握 Hive SQL 的一些高级特性,比如窗口函数、分区等等。对于初学者而言,写出高效的 Hive SQL 代码往往是一件困难的事情,而这恰恰是面试官最为看重的。但是,你不必担心!现在,有一种神奇的工具——ChatGPT,可以帮助你快速生成 Hive SQL 代码,解决你在面试中遇到的各种难题。本文将会介绍如何使用 ChatGPT 生成 Hive SQL 代码,让你在面试中轻松成为 Hive SQL 面试高手,无需编写代码也能毫不费力地完成面试题。 让我们一起来看看吧!
|
SQL 分布式计算 Hadoop
【Hadoop技术篇】hive的优化,经典面试
1) 开启配置:set hive.optimize.bucketmapjoin = true; 2) 一个表的bucket数是另一个表bucket数的==整数倍== 3) bucket列 == join列 4) 满足map join条件
356 0
|
SQL 存储 分布式计算
【大数据面试题】(二)Hive 相关面试题总结
【大数据面试题】(二)Hive 相关面试题总结
346 0
【大数据面试题】(二)Hive 相关面试题总结
|
SQL 存储 运维
精选Hive高频面试题11道,附答案详细解析(好文收藏)(一)
精选Hive高频面试题11道,附答案详细解析
706 0
精选Hive高频面试题11道,附答案详细解析(好文收藏)(一)

热门文章

最新文章