db2中聚合函数如果没有记录会怎样_搞定数分面试必考题之窗口函数

本文深入探讨SQL窗口函数,包括基本语法、静态与动态函数,以及滑动窗口的使用。通过实例展示了窗口函数如何进行分组、排序、计算累计和平均值,同时对比了窗口函数与GROUP BY的区别。文章还进一步讲解了窗口函数在解决Top N问题、连续登录天数等实际问题中的应用,帮助读者掌握这一重要的数据分析工具。
摘要由CSDN通过智能技术生成

点击关注上方“Python数据分析实例”

设为“置顶或星标”,送达干货不错过!

窗口函数的主要作用是对数据进行分组排序、求和、求平均值、计数等。对于数据从业者来说, sql窗口函数在实际工作中具备非常广泛的应用场景。可以大大的提高数据查询效率,同时也是数据类相关岗位的面试/笔试的必考点。所以不论是在职的分析师,还是准备找工作的同学,都必须要牢牢掌握窗口函数的概念及用法。感谢群友饭小米的投稿,接下来让我们详细了解一下窗口函数的前世今生吧。

1937b78bcdd10791156618d88614c4cf.png  窗口函数基本语法

93d1af0a3af64832783b2d9d3bd03031.png

在窗口函数的基本语法中,最重要的是去理解partition by,partition by划分的范围被称为窗口,这也是窗口函数的由来。其次是order by,它决定着窗口范围内的数据以什么样的方式排序。下面的例子详细的介绍了窗口函数的基本语法和功能。

例一 代码如下

1cdc6593a1ea2776c6300abaf28063cb.png

在上面的代码中可以看出,是按照产品的类型去分组,在组内以价格的顺序升序排列,运行的结果如下。(rank的排序下面会单独说)

7c0ba6f4d0c786b68bfc80c77ff783ce.png

至于窗口函数与group by的区别:

  • 两个order by的区别,第一个窗口函数中的order by只是决定着窗口里的数据的排序方式,第二个普通的order by决定查询出的数据以什么样的方式整体排序;

  • 窗口函数可以在保留原表中的全部数据之后,可以对某些字段做分组排序或者计算,而group by只能保留与分组字段聚合的结果;

  • 在加入窗口函数的基础上SQL的执行顺序也会发生变化,具体的执行顺序如下(window就是窗口函数);

762942447ffb81dc8a41a7eff8ab80d0.png

fd9cfc8276d88b7016a8bf24292f12ba.png

窗口函数类别

专用窗口函数例如rank、row_number、lag和lead等,在窗口函数中有静态函数和动态函数的分类,具体的划分如下。

3f16a4024c534d61c83924bc811b4e7d.png

作为窗口函数的聚合函数,常见的聚合函数有sum、avg、max、min跟count。他们跟窗口函数组合到一起,就会把聚合函数的功能和窗口函数组合在一起。

例二 代码及结果为

5519d222a2de4998d5afce51bc9e8adc.png

7c1abbf837d24e791b9ed0bdad414968.png

从上面的例子可以看出,在没有partition by 的情况下,是把整个表作为一个大的窗口,SUM()相当于向下累加,AVG()相当于求从第一行到当前行的平均值,其他的聚合函数均是如此。

注意点:

1 、在使用专用的窗口函数时,例如rank、lag等,rank()括号里是不需要指定任何字段的,直接空着就可以;

2 、在使用聚合函数做窗口函数时,SUM()括号里必须有字段,得指定对哪些字段执行聚合的操作。在学习的初期很容易弄混,不同函数括号里是否需写相应的字段名;

6190e884faefb2390d488d652b365207.png

三种分组排序的区别- row_number、rank、dense_rank
  • RANK-计算排序时,如果存在相同位次的记录,则会跳过之后的位次。有 3 条记录排在第 1 位时:1 、1 、1 、4;

  • DENSE_RANK-同样是计算排序,即使存在相同位次的记录,也不会跳过之后的位次。有 3 条记录排在第 1 位时:1 、1 、1 、2;

  • ROW_NUMBER-赋予唯一的连续位次,有 3 条记录排在第 1 位时:1 、2 、3 、4;

示例,在下面的执行结果是以整个表作为窗口,可以清楚的看出三种排序函数的不同之处。(如果想要唯一的排序就直接用row_number)

482994359e2371fa3826ebb24e1440fb.png

e0a4c629d5a13a7fa6c1f7137c1b24ae.png

窗口函数进阶-滑动窗口函数

在写窗口函数时,order by后面可以有参数,rows/range 和preceding跟following,在组合使用这些参数后,窗口就会变成滑动窗口,因为涉及到动态窗口,所以在理解上比较抽象。

1、 Preceding

364d8def83106e2363e2ac52f5ba88e7.png

a2d58cd03034b2d47dca27a03a8f6e50.png

Rows 2 preceding 中文的意思是之前的两行,preceding可以把它理解为不含当前行情况下截止到之前几行。根据上图可以看出在每一行,都会求出当前行附近的3行(当前行+附近2行)数据的平均值,这种方法也叫作移动平均

2、Following

Rows 2 following 中文意思是之后的两行,跟preceding正好相反,Preceding是向前,following是向后。

462e2aa61fea0e9acb4758a0ac204072.png

3、preceding跟following相结合

代码及运行结果为:

a5cecf6a5f0e8ee0f83198c082d92bee.png

43d4b607f60a6a684e159dd87ce91d49.png

从以上的运行结果可以看出是把每一行(当前行)的前一行和后一行作为汇总的依据。

486974979732365a60f6fe2efc1f54a9.png窗口函数应用真题解析

1、topN问题或者组内排序问题

在实际的场景中,我们会经常会遇到排序或者排名问题,这个时候使用窗口函数会使问题变的简单。

求出每个课程的学生成绩排名:

4209ba662392968b6d2c4fcfa41e69e8.png

2、连续登录问题

假设有一张含两列(用户id、登陆日期)的表,查询每个用户连续登陆的天数、最早登录时间、最晚登录时间和登录次数。

  • 首先要对数据进行去重,防止同一个用户一天之内出现连续登录的情况;

  • 假如一个用户是连续登录的话,用login_time-窗口函数的排序后得到的日期应该是一样的,连续登录的用户前后之间的时间差就是一个差值为1的等差数列;

第一步,先用row_number()函数排序,然后用登录日期减去排名,得到辅助列日期,如果辅助列日期是相同的话,证明用户是连续登录。

运行的代码及结果为:

4b0504ea788bdb9c0321aa880b45cf18.png

94cc48917e502fcef534bd41d6defc0d.png

第二步,用user_id和辅助列作为分组依据,分到一组的就是连续登录的用户。在每一组中最小的日期就是最早的登陆日期,最大的日期就是最近的登陆日期,对每个组内的用户进行计数就是用户连续登录的天数。

运行代码及结果为:

72bedfe13958157e8a7c47a6184dcd66.png

005da9102adbb5cd8e2ef53286b546be.png

若求解每个用户的最大登录天数。其实可以在以上的查询结果为基础,利用聚合函数就可以求出最大的登录天数问题。假如求解连续登录5天的用户,除了可以使用上述的方法,还可以使用lead函数进行窗口偏移来进行求解。

示例:数据还是上题中的数据,求解连续登录五天的用户

第一步,用lead函数进行窗口偏移,查找每个用户5天后的登陆日期是多少,如果是空值,说明他没有登录。运行的代码为

45e74ac6c09bc41b145f293c2390cc2e.png

在lead函数里,为何偏移行数的参数设置为4而不是5呢,这是因为求解的是连续登录5天的用户,包括当前行在内一共是5行,所以应该向下偏移4行。运行的结果如下:

9f1a2b572ff9a6897ab0c9ef62a895a8.png

第二步,用datediff函数计算 (日期-第五次登陆日期)+1是否等于5,等于5证明用户是连续5天登录的,为空值或者大于5都不是5天连续登陆的用户。

第三步,用where设定条件,差值=5筛选连续登录的用户。

二、三步运行的代码为:

d1a64cda8e763b1e944d9495ffbeeb8b.png

用lead函数求解连续登录的问题还有一个好处就是当表中的数据不在同一个月份时也可以完美的解决,不用再考虑月份带来的影响。


熟练掌握本篇所提到的用法,即可轻松应对绝大部分数据分析面试中的窗口函数考题,窗口函数,你了解了吗?

感谢大家的阅读,关注小洛的公众号,一起交流数据分析话题~ 

1982dabca7398d17cd5ad4d9d4b52ec8.png

微信改版,快快设为星标记得点在看?
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值