APP推广合作
联系“鸟哥笔记小乔”
【面试必问】窗口函数全解-HIVE
2020-08-26 22:17:17

这是我的第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

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

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


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


往期精彩回顾




解密 | 专业HR角度解析完美简历
实操 | 数据驱动业务全解
热文 | MapReduce环形缓冲区

转发,点赞,在看,安排一下?
大数据架构师
分享到朋友圈
收藏
收藏
评分

综合评分:

我的评分
Xinstall 15天会员特权
Xinstall是专业的数据分析服务商,帮企业追踪渠道安装来源、裂变拉新统计、广告流量指导等,广泛应用于广告效果统计、APP地推与CPS/CPA归属统计等方面。
20羽毛
立即兑换
一书一课30天会员体验卡
领30天VIP会员,110+门职场大课,250+本精读好书免费学!助你提升职场力!
20羽毛
立即兑换
顺丰同城急送全国通用20元优惠券
顺丰同城急送是顺丰推出的平均1小时送全城的即时快送服务,专业安全,准时送达!
30羽毛
立即兑换
大数据架构师
大数据架构师
发表文章269
历任多家公司大数据总监、大数据架构师,专注于数字化转型领域。
确认要消耗 羽毛购买
【面试必问】窗口函数全解-HIVE吗?
考虑一下
很遗憾,羽毛不足
我知道了

我们致力于提供一个高质量内容的交流平台。为落实国家互联网信息办公室“依法管网、依法办网、依法上网”的要求,为完善跟帖评论自律管理,为了保护用户创造的内容、维护开放、真实、专业的平台氛围,我们团队将依据本公约中的条款对注册用户和发布在本平台的内容进行管理。平台鼓励用户创作、发布优质内容,同时也将采取必要措施管理违法、侵权或有其他不良影响的网络信息。


一、根据《网络信息内容生态治理规定》《中华人民共和国未成年人保护法》等法律法规,对以下违法、不良信息或存在危害的行为进行处理。
1. 违反法律法规的信息,主要表现为:
    1)反对宪法所确定的基本原则;
    2)危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一,损害国家荣誉和利益;
    3)侮辱、滥用英烈形象,歪曲、丑化、亵渎、否定英雄烈士事迹和精神,以侮辱、诽谤或者其他方式侵害英雄烈士的姓名、肖像、名誉、荣誉;
    4)宣扬恐怖主义、极端主义或者煽动实施恐怖活动、极端主义活动;
    5)煽动民族仇恨、民族歧视,破坏民族团结;
    6)破坏国家宗教政策,宣扬邪教和封建迷信;
    7)散布谣言,扰乱社会秩序,破坏社会稳定;
    8)宣扬淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪;
    9)煽动非法集会、结社、游行、示威、聚众扰乱社会秩序;
    10)侮辱或者诽谤他人,侵害他人名誉、隐私和其他合法权益;
    11)通过网络以文字、图片、音视频等形式,对未成年人实施侮辱、诽谤、威胁或者恶意损害未成年人形象进行网络欺凌的;
    12)危害未成年人身心健康的;
    13)含有法律、行政法规禁止的其他内容;


2. 不友善:不尊重用户及其所贡献内容的信息或行为。主要表现为:
    1)轻蔑:贬低、轻视他人及其劳动成果;
    2)诽谤:捏造、散布虚假事实,损害他人名誉;
    3)嘲讽:以比喻、夸张、侮辱性的手法对他人或其行为进行揭露或描述,以此来激怒他人;
    4)挑衅:以不友好的方式激怒他人,意图使对方对自己的言论作出回应,蓄意制造事端;
    5)羞辱:贬低他人的能力、行为、生理或身份特征,让对方难堪;
    6)谩骂:以不文明的语言对他人进行负面评价;
    7)歧视:煽动人群歧视、地域歧视等,针对他人的民族、种族、宗教、性取向、性别、年龄、地域、生理特征等身份或者归类的攻击;
    8)威胁:许诺以不良的后果来迫使他人服从自己的意志;


3. 发布垃圾广告信息:以推广曝光为目的,发布影响用户体验、扰乱本网站秩序的内容,或进行相关行为。主要表现为:
    1)多次发布包含售卖产品、提供服务、宣传推广内容的垃圾广告。包括但不限于以下几种形式:
    2)单个帐号多次发布包含垃圾广告的内容;
    3)多个广告帐号互相配合发布、传播包含垃圾广告的内容;
    4)多次发布包含欺骗性外链的内容,如未注明的淘宝客链接、跳转网站等,诱骗用户点击链接
    5)发布大量包含推广链接、产品、品牌等内容获取搜索引擎中的不正当曝光;
    6)购买或出售帐号之间虚假地互动,发布干扰网站秩序的推广内容及相关交易。
    7)发布包含欺骗性的恶意营销内容,如通过伪造经历、冒充他人等方式进行恶意营销;
    8)使用特殊符号、图片等方式规避垃圾广告内容审核的广告内容。


4. 色情低俗信息,主要表现为:
    1)包含自己或他人性经验的细节描述或露骨的感受描述;
    2)涉及色情段子、两性笑话的低俗内容;
    3)配图、头图中包含庸俗或挑逗性图片的内容;
    4)带有性暗示、性挑逗等易使人产生性联想;
    5)展现血腥、惊悚、残忍等致人身心不适;
    6)炒作绯闻、丑闻、劣迹等;
    7)宣扬低俗、庸俗、媚俗内容。


5. 不实信息,主要表现为:
    1)可能存在事实性错误或者造谣等内容;
    2)存在事实夸大、伪造虚假经历等误导他人的内容;
    3)伪造身份、冒充他人,通过头像、用户名等个人信息暗示自己具有特定身份,或与特定机构或个人存在关联。


6. 传播封建迷信,主要表现为:
    1)找人算命、测字、占卜、解梦、化解厄运、使用迷信方式治病;
    2)求推荐算命看相大师;
    3)针对具体风水等问题进行求助或咨询;
    4)问自己或他人的八字、六爻、星盘、手相、面相、五行缺失,包括通过占卜方法问婚姻、前程、运势,东西宠物丢了能不能找回、取名改名等;


7. 文章标题党,主要表现为:
    1)以各种夸张、猎奇、不合常理的表现手法等行为来诱导用户;
    2)内容与标题之间存在严重不实或者原意扭曲;
    3)使用夸张标题,内容与标题严重不符的。


8.「饭圈」乱象行为,主要表现为:
    1)诱导未成年人应援集资、高额消费、投票打榜
    2)粉丝互撕谩骂、拉踩引战、造谣攻击、人肉搜索、侵犯隐私
    3)鼓动「饭圈」粉丝攀比炫富、奢靡享乐等行为
    4)以号召粉丝、雇用网络水军、「养号」形式刷量控评等行为
    5)通过「蹭热点」、制造话题等形式干扰舆论,影响传播秩序


9. 其他危害行为或内容,主要表现为:
    1)可能引发未成年人模仿不安全行为和违反社会公德行为、诱导未成年人不良嗜好影响未成年人身心健康的;
    2)不当评述自然灾害、重大事故等灾难的;
    3)美化、粉饰侵略战争行为的;
    4)法律、行政法规禁止,或可能对网络生态造成不良影响的其他内容。


二、违规处罚
本网站通过主动发现和接受用户举报两种方式收集违规行为信息。所有有意的降低内容质量、伤害平台氛围及欺凌未成年人或危害未成年人身心健康的行为都是不能容忍的。
当一个用户发布违规内容时,本网站将依据相关用户违规情节严重程度,对帐号进行禁言 1 天、7 天、15 天直至永久禁言或封停账号的处罚。当涉及欺凌未成年人、危害未成年人身心健康、通过作弊手段注册、使用帐号,或者滥用多个帐号发布违规内容时,本网站将加重处罚。


三、申诉
随着平台管理经验的不断丰富,本网站出于维护本网站氛围和秩序的目的,将不断完善本公约。
如果本网站用户对本网站基于本公约规定做出的处理有异议,可以通过「建议反馈」功能向本网站进行反馈。
(规则的最终解释权归属本网站所有)

我知道了
恭喜你~答对了
+5羽毛
下一次认真读哦
成功推荐给其他人
+ 10羽毛
评论成功且进入审核!审核通过后,您将获得10羽毛的奖励。分享本文章给好友阅读最高再得15羽毛~
(羽毛可至 "羽毛精选" 兑换礼品)
好友微信扫一扫
复制链接