含泪整理的超全窗口函数:数据开发必备

news2024/10/5 19:15:36

最近在搞一些面试和课程答辩的时候,问什么是窗口函数,知道哪些窗口函数?最多的答案就是row_number、rank、dense_rank,在问一下还有其他的吗?这时同学就蒙了,还有其他的窗口函数?其实上面的回答也只是专用窗口函数,并不是窗口函数的整体定义,那今天我们就来好好聊聊窗口函数。

1.窗口函数概念

我们首先来谈谈什么是窗口函数,窗口函数是指,在指定的数据滑动窗口中,实现各种统计分析的操作。窗口函数是与分析函数一起使用,或按照专用窗口函数使用,组成比如:窗口聚合函数、窗口排序函数等实用函数。

常用的分析函数:sum()、max()、min()、avg()、count()、......
专用窗口函数:row_number()、rank()、dense_rank()......

具体语法

这个很重要,只要满足这个语法的都算窗口函数,具体使用语法如下:

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

窗口函数的3个组成部分可以单独使用,也可以混合使用,也可以全都不用,下面是三部分的详细解释。

1.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

注意:聚合函数是将多条记录聚合为一条;窗口函数是每条记录都会执行,有几条记录执行完还是几条。窗口函数兼具GROUP BY 子句的分组功能以及ORDER BY 子句的排序功能。但是,PARTITION BY 子句并不具备 GROUP BY 子句的汇总功能。

2.order by 字段

大家都知道order by 是排序字段,(这里多说一句四个不要的区别理解了吗?),它用在窗口函数里会有不一样的效果。

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

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


情景二:当为聚合函数,如max,min,count等时,over中的order by不仅起到窗⼝内排序,还起到窗⼝内从当前⾏到之前所有⾏的聚合(多了⼀个范围)。

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

with temp_01 as(
select 'A' as user_id,1 as cnt
union all
select 'D' as user_id,2 as cnt
  union all
select 'D' as user_id,3 as cnt
union all
select 'B' as user_id,4 as cnt
union all
select 'B' as user_id,5 as cnt
)
select user_id,sum(cnt) over(partition by user_id) as sum_all from temp_01
select user_id,sum(cnt) over(partition by user_id order by cnt) as sum_all from temp_01

情景三:当排序的维度不存在重复的情况下,即 order by 指定的字段,使用 order by + 分析函数 sum(),可以产生求整体累计数的效果。但是当 order by 指定的字段组合,数据存在重复的时候,会在不重复的数据中产生累计效果,而重复的数据中,也是会把整体的累计结果分发到每条重复的数据中。

with temp_01 as(
select 'A' as user_id,1 as cnt
union all
select 'D' as user_id,2 as cnt
  union all
select 'D' as user_id,3 as cnt
union all
select 'B' as user_id,4 as cnt
union all
select 'B' as user_id,4 as cnt
)
select user_id,sum(cnt) over(partition by user_id order by cnt) as sum_all from temp_01

3.rows between 开始位置 and 结束位置

rows between 是指划分窗口中,函数具体的作用数据范围。rows between 常用的参数如下:

n preceding:往前
n following:往后
current row:当前行
unbounded:起点(一般结合preceding,following使用)

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

这些参数需要好好记忆,使用例子如下:

1.rows between unbounded preceding and current row(表示从起点到当前行的数据进行);

2.rows between current row and unbounded following(表示当前行到终点的数据进行);

3.rows between unbounded preceding and unbounded following (表示起点到终点的数据);

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

with temp_01 as(
select 'D' as user_id,2 as cnt
  union all
select 'D' as user_id,2 as cnt
union all
select 'B' as user_id,4 as cnt
union all
select 'B' as user_id,5 as cnt
  union all
  select 'A' as user_id,1 as cnt
)
select user_id,cnt,sum(cnt) over(partition by user_id  order by cnt  rows between unbounded preceding and current row) as sum_all from temp_01

2.窗口函数分类

说过了什么是窗口函数,明白什么是窗口函数,所以以后面试过程中问到什么是窗口函数,不要在简单的说排序啦,接下来我们在谈谈具体有哪些函数。

2.1 排序窗口函数

这个就是大家最熟悉,或者也只能回答出来的函数了;

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

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

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


2.2 聚合窗口函数

聚合函数配置over形成的窗口函数,可以在是我们实际工作中用到累计,窗口中平均值、窗口中最大值最小值等的场景。

求窗口中的累计值

我们可以使用:sum() over();

求窗口中 3 天的平均价格

我们可以使用 avg() over();


输出结果:


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

max() over() as 窗口中的最大值
min() over() as 窗口中的最小值

求分组中的总记录数

我们可以使用 count() over()

举了两个简单的例子,可以参考例子更容易让大家理解。

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

2.3 位移窗口函数

获取分组中往前 n 行的值

基础语法:lead(field,n,default_value) over()

获取分组中往后 n 行的值

基础语法:lag(field,n, default_value) over()

2.4 极值窗口函数

获取分组内第一行的值

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

注意:

1.当第二个参数为 true 的时候,会跳过空值;  

2.当 over() 中不指定排序的时候,会默认使用表中数据的原排序。

获取分组内最后一行的值

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

注意:

1.当第二个参数为 true 的时候,会跳过空值;

2.当 over() 中不指定排序的时候,会默认使用表中数据的原排序。

3.当 over() 中指定排序的时候,要与 rows between unbounded preceding and unbounded following 连用。


2.5 分箱窗口函数

ntile() over() 分箱窗口函数,多用于统计百分比,用于将分组数据按照顺序切分成 n 片,返回当前切片值,如果切片不均匀,默认增加到第一个切片中。

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


输出结果


相信介绍到这里,我们对于什么是窗口函数,有哪些窗口函数都有了一个全面的认识了,面试中我们就按照这样的分类一一介绍,来打动我们的面试官。 

含泪整理的超全窗口函数:数据开发必备

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多门店自助点餐+外卖二合一小程序源码系统 带完整搭建教程

随着餐饮业的快速发展和互联网技术的不断进步,越来越多的餐厅开始采用自助点餐和外卖服务。市场上许多的外卖小程序APP应运而生。下面罗峰来给大家介绍一款多门店自助点餐外卖二合一小程序源码系统。该系统结合了自助点餐和外卖服务的优势,为餐厅提供了一…

照明灯具哪个品牌好?照明灯具十大排行榜

现在儿童近视率越来越高了,用眼过度疲劳是导致近视的主要因素,学习环境的光线是否合适,都会直接影响用眼的疲劳程度。所以给孩子营造一个良好的学习环境非常重要!一款护眼台灯可以很好的预防近视,为大家推荐五款护眼台…

【今日文章】:如何用css 实现星空效果

【今日文章】:如何用css 实现星空效果 需求实现tips: 需求 用CSS 实现星空效果的需求: 屏幕上有“星星”,且向上移动。移动的时候,动画效果要连贯,不能出现闪一下的样子。 实现 这里我们需要知道,“星星”是…

复杂逻辑的开发利器—Mendix快速实现AQL质量抽检

Mendix低代码开发平台适用于复杂的业务逻辑场景,这句话大家早有耳闻,本期小编就为您打开智慧之光,仅从AQL小侧面,来管窥一二——Mendix如何形成第五代编程语言,来完成数据逻辑与建模、业务算法逻辑与建模的。&#xff…

Excel下拉填充时,如何使得数字不递增?

问题描述:Excel下拉填充时,如何使得数字不递增? 解决办法:先下拉填充数据之后,看到最后一个单元格的右下角有个填充设置的符号,右键选择复制单元格即可。其中这里的填充序列就是递增数字的操作。

塔望食研院|骆驼奶市场规模庞大,百亿体量,品牌升级!

自2022年12月塔望咨询开设塔望食品大健康行业与消费研究院(简称塔望食研院)栏目以来,塔望食研院以“为食品行业品牌高质量发展赋能”为理念,不断发布食品大健康行业研究、消费研究报告。塔望食研院致力于结合消费调研数据、企业数…

如何使用ESB产品对接业务系统接口

ESB企业服务总线在实际项目中主要用于各业务系统之间的集成,集成包括数据集成、应用集成以及业务单据集成等,ESB企业服务总线主要包含三部分:ESB设计器、SMC管理控制台以及Server运行环境,ESB设计器用于服务以及集成流程的开发&am…

AI时代项目经理与架构师的成长之道:ChatGPT让你插上翅膀

💂 个人网站:【工具大全】【游戏大全】【神级源码资源网】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 寻找学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 在AI时代,项…

Ubuntu中增加交换内存

前言 在运行一些代码编译或者clang-format会占用大量的内存,此时可能会出现电脑卡死的情况,在ubuntu中可以通过增加交换内存来临时解决这个问题,相对于硬件改动成本更低,但是性能不如物理内存。 实践 查看当前的交换内存大小 …

【MySQL日志与备份篇】主从复制

主从复制 文章目录 主从复制1. 概述2. 主从复制的原理2.1 原理剖析2.2 复制的基本原则 3. 一主一从架构搭建3.1 准备工作3.2 主机配置文件3.3 从机配置文件3.4 主机:建立账户并授权3.5 从机:配置需要复制的主机3.6 停止主从同步3.7 后续 4. 同步数据一致…

关于WMS三个核心问题的解读

一、企业是否需要上WMS系统,可以从以下五个方面入手: 1.库存管理状况:了解企业的库存管理状况,是否存在库存冗余、漏洞、过度采购、库存盘点不准确等问题。 2.物流效率水平:需要了解企业物流效率水平,包括…

全网最全的设计模式专栏完结,建议点赞收藏

引言 代码写得烂可能并不是他的问题,推这个专栏给他看看。 本系列是《和8年游戏主程一起学习设计模式》,让糟糕的代码在潜移默化中升华。 大家好,白驹过隙,岁月如梭。本系列文章终于迎来了完结,距离开始已经一个多月…

阿里云Intel Xeon Platinum可扩展处理器性能如何?

阿里云Intel Xeon Platinum可扩展处理器性能如何?目前云服务器ECS经济型e实例采用该款CPU型号,正好阿里云服务器网购买了一台2核CPU、2G内存、3M固定带宽、40G ESSD Entry云盘,一年优惠价99元,第二年续费不涨价依旧是99元一年&…

nerdctl install【nerdctl 安装】

文章目录 1. 在线安装2. 离线安装 1. 在线安装 #!/bin/bashsource ./config.shENABLE_DOWNLOAD${ENABLE_DOWNLOAD:-true}if [ ! -e files ]; thenmkdir -p files fiFILES_DIR./files if $ENABLE_DOWNLOAD; thenFILES_DIR./tmp/filesmkdir -p $FILES_DIR fi# download files, i…

25期代码随想录算法训练营第十天 | 栈与队列 part 1

目录 232.用栈实现队列225. 用队列实现栈 232.用栈实现队列 链接 相当于用两个stack将队列的元素顺序颠倒了一遍。 class MyQueue:def __init__(self):self.stack_in []self.stack_out []def push(self, x: int) -> None:self.stack_in.append(x)def pop(self) -> in…

《2023中国各地区科创之星势力图2.0版》重磅发布

数据猿出品 本次“数据猿2023年度三大媒体策划活动——《2023中国各地区科创之星势力图2.0版》”的发布,是数据猿在2023年1.0版本的基础上,迭代升级的2023开年的第二个版本。本年度下一次版本迭代将于2024年1月发布2023年3.0版,敬请期待&…

SpringCloud 微服务全栈体系(十三)

第十一章 分布式搜索引擎 elasticsearch 二、索引库操作 索引库就类似数据库表,mapping 映射就类似表的结构。 我们要向 es 中存储数据,必须先创建“库”和“表”。 1. mapping 映射属性 mapping 是对索引库中文档的约束,常见的 mapping …

王道p18 第12题假设 A中的 n个元素保存在一个一维数组中,请设计一个尽可能高效的算法,找出A的主元素。若存在主元素,则输出该元素:否则输出-1

视频讲解在:👇 p18 第12题 c语言实现王道数据结构课后习题_哔哩哔哩_bilibili 从前向后扫描数组元素,标记出一个可能成为主元素的元素 Num。然后重新计数,确认 Num 是否是主元素。 我们可分为以下两步: 1.选取候选的主元素。依…

JVM运行时数据区-虚拟机栈

目录 一、内存中的栈 二、基本内容 三、优点 四、栈的存储单位 五、栈运行原理 六、栈的内部结构 (一)局部变量表 (二)操作数栈 (三)动态链接 (四)方法返回地址 &#xf…

接口开发之使用C#插件Quartz.Net定时执行CMD任务工具

C#制作定时任务工具执行CMD命令 概要准备知识点实现原理thinkphp配置winform执行CMD命令读取ini配置文件定时任务Quartz.Net 完整代码Job.csIniFunc.csForm1.csconfig.ini简易定时任务工具雏形 概要 很多时候写接口上线后还会遇到很多修改,类似JAVA,C#,delphi制作的…