热门标签 | 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函数求解连续登录的问题还有一个好处就是当表中的数据不在同一个月份时也可以完美的解决,不用再考虑月份带来的影响。


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

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


推荐阅读
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • 如何将Python与Excel高效结合:常用操作技巧解析
    本文深入探讨了如何将Python与Excel高效结合,涵盖了一系列实用的操作技巧。文章内容详尽,步骤清晰,注重细节处理,旨在帮助读者掌握Python与Excel之间的无缝对接方法,提升数据处理效率。 ... [详细]
  • 基于iSCSI的SQL Server 2012群集测试(一)SQL群集安装
    一、测试需求介绍与准备公司计划服务器迁移过程计划同时上线SQLServer2012,引入SQLServer2012群集提高高可用性,需要对SQLServ ... [详细]
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • Spark与HBase结合处理大规模流量数据结构设计
    本文将详细介绍如何利用Spark和HBase进行大规模流量数据的分析与处理,包括数据结构的设计和优化方法。 ... [详细]
  • 在PHP中如何正确调用JavaScript变量及定义PHP变量的方法详解 ... [详细]
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 本文详细介绍了在MySQL中如何高效利用EXPLAIN命令进行查询优化。通过实例解析和步骤说明,文章旨在帮助读者深入理解EXPLAIN命令的工作原理及其在性能调优中的应用,内容通俗易懂且结构清晰,适合各水平的数据库管理员和技术人员参考学习。 ... [详细]
  • 在《Linux高性能服务器编程》一书中,第3.2节深入探讨了TCP报头的结构与功能。TCP报头是每个TCP数据段中不可或缺的部分,它不仅包含了源端口和目的端口的信息,还负责管理TCP连接的状态和控制。本节内容详尽地解析了TCP报头的各项字段及其作用,为读者提供了深入理解TCP协议的基础。 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 如何优化MySQL数据库性能以提升查询效率和系统稳定性 ... [详细]
  • 当使用 `new` 表达式(即通过 `new` 动态创建对象)时,会发生两件事:首先,内存被分配用于存储新对象;其次,该对象的构造函数被调用以初始化对象。为了确保资源管理的一致性和避免内存泄漏,建议在使用 `new` 和 `delete` 时保持形式一致。例如,如果使用 `new[]` 分配数组,则应使用 `delete[]` 来释放内存;同样,如果使用 `new` 分配单个对象,则应使用 `delete` 来释放内存。这种一致性有助于防止常见的编程错误,提高代码的健壮性和可维护性。 ... [详细]
  • MyISAM和InnoDB是MySQL中最为广泛使用的两种存储引擎,每种引擎都有其独特的优势和适用场景。MyISAM引擎以其简单的结构和高效的读取速度著称,适用于以读操作为主、对事务支持要求不高的应用。而InnoDB引擎则以其强大的事务处理能力和行级锁定机制,在需要高并发写操作和数据完整性的场景下表现出色。选择合适的存储引擎应综合考虑业务需求、性能要求和数据一致性等因素。 ... [详细]
  • SSAS入门指南:基础知识与核心概念解析
    ### SSAS入门指南:基础知识与核心概念解析Analysis Services 是一种专为决策支持和商业智能(BI)解决方案设计的数据引擎。该引擎能够为报告和客户端应用提供高效的分析数据,并支持在多维数据模型中构建高性能的分析应用。通过其强大的数据处理能力和灵活的数据建模功能,Analysis Services 成为了现代 BI 系统的重要组成部分。 ... [详细]
  • 使用 `git stash` 可以将当前未提交的修改保存到一个临时存储区,以便在后续恢复工作目录时使用。例如,在处理中间状态时,可以通过 `git stash` 命令将当前的所有未提交更改推送到一个新的储藏中,从而保持工作目录的整洁。此外,本文还将详细介绍如何解决 `git stash pop` 时可能出现的冲突问题,帮助用户高效地管理代码变更。 ... [详细]
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社区 版权所有