热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

一文搞定数分面试必考题之:窗口函数

小洛写在前面:窗口函数的主要作用是对数据进行分组排序、求和、求平均值、计数等。对于数据从业者来说,sql窗口函数在实际工作中具备非常广泛的应用场景。可以

小洛写在前面:

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

 

 窗口函数基本语法

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

 

例一 代码如下

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

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

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

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

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

窗口函数类别

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

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

 

例二 代码及结果为

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

 

注意点:

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

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

 

三种分组排序的区别-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)

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

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

1、 Preceding

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

2、Following

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

3、preceding跟following相结合

代码及运行结果为:

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

 

窗口函数应用真题解析

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

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

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

2、连续登录问题

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

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

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

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

运行的代码及结果为:

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

运行代码及结果为:

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

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

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

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

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

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

二、三步运行的代码为:

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


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

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


推荐阅读
  • 本文介绍了利用ARMA模型对平稳非白噪声序列进行建模的步骤及代码实现。首先对观察值序列进行样本自相关系数和样本偏自相关系数的计算,然后根据这些系数的性质选择适当的ARMA模型进行拟合,并估计模型中的位置参数。接着进行模型的有效性检验,如果不通过则重新选择模型再拟合,如果通过则进行模型优化。最后利用拟合模型预测序列的未来走势。文章还介绍了绘制时序图、平稳性检验、白噪声检验、确定ARMA阶数和预测未来走势的代码实现。 ... [详细]
  • 本文介绍了Python语言程序设计中文件和数据格式化的操作,包括使用np.savetext保存文本文件,对文本文件和二进制文件进行统一的操作步骤,以及使用Numpy模块进行数据可视化编程的指南。同时还提供了一些关于Python的测试题。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • Explain如何助力SQL语句的优化及其分析方法
    本文介绍了Explain如何助力SQL语句的优化以及分析方法。Explain是一个数据库SQL语句的模拟器,通过对SQL语句的模拟返回一个性能分析表,从而帮助工程师了解程序运行缓慢的原因。文章还介绍了Explain运行方法以及如何分析Explain表格中各个字段的含义。MySQL 5.5开始支持Explain功能,但仅限于select语句,而MySQL 5.7逐渐支持对update、delete和insert语句的模拟和分析。 ... [详细]
  • 颜色迁移(reinhard VS welsh)
    不要谈什么天分,运气,你需要的是一个截稿日,以及一个不交稿就能打爆你狗头的人,然后你就会被自己的才华吓到。------ ... [详细]
  • oracle恢复失败,RMAN数据库恢复失败解决一例
    问题:这是一个从RAC环境的数据库的RAMN备份恢复到一个单机数据库的操作。当恢复数据文件和恢复正常,但在open数据库时出报下面的错误。--rman备 ... [详细]
author-avatar
天使的眼泪174
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有