摘要:本文由葡萄城技术团队于博客园原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。

前言

SQL语句中,聚合函数在统计业务数据结果时起到了重要作用,比如计算每个业务地区的业务总数、每个班级的学生平均分以及每个分类的最大值等。然而,今天我将介绍窗口函数,与聚合函数相比,它们也是一组函数,但在使用方法和适用场景上有所不同。在本章节中,我将重点介绍窗口函数中的RANK和DENSE_RANK函数,以及它们在排名和筛选方面的应用场景。这些窗口函数可以帮助我们更灵活地处理数据并获得所需的结果,需要注意的是,目前主流的数据库对窗口函数的最低需求版本如下:

Mysql (>=8.0)

PostgreSQL(>=8.4)

SQL Server(>2005)

SQLite(>3.25.0)

如果您的数据库版本低于上述要求,将无法使用窗口函数。

需求背景:

为了让大家更好的理解,我将以学生数据作为查询的条件背景:假设现在某个学校的某个年级的同学完成了一次考试,成绩也已经录入到数据库中:

现在该年级的教务主任想要看一下:

1.这次考试本年级各个科目的前2名的同学。

2.这次考试每个班级中各个科目的前2名。

3.这次考试每个班级中的总分排名前2名。

如果用普通的SQL查询即麻烦也费时间,而使用RANK和DENSE_RANK函数就可以很快的查询出想要的学生数据,下面将为大家介绍如何使用RANK和DENSE_RANK函数实现学生数据的查询。

使用聚RANK和DENSE_RANK函数查询学生数据

1.查询本年级各个科目前2名的同学。

为了获得各个不同科目各自的前2名,我们需要先使用 Rank() 函数来给每个学生在各自科目的分区打上成绩排名, 执行如下SQL 语句,查询出来的结果如下图。

select sd.*, RANK() over(partition by subject order by score desc) as _rank from score_data sd;

可以看到,执行结果里面已经根据各个科目的成绩得到了排名字段 _rank, 接下来只需要使用过滤掉 _rank 字段大于2的部分即可,查询的结果如下图所示。

select * from (

select sd.*, RANK() over(partition by subject order by score desc) as _rank from score_data sd

) tmp

where tmp._rank <=2

从上图中看到如果存在成绩一样的情况,就会出现像数学科目的查询结果:数学查询出来了三个值(因为有两个人的数学成绩是一样的77分),如果我们只想保留一条重复的数据,我们可以使用DENSE_RANK函数,这个函数的计算语法和 RANK 基本一致,唯一不同的点在于, Rank 计算时会得到成绩高于当前行的记录的总行数,也就是上图查询出来的数学科目的三条数据,而DENSE_RANK 则是计算成绩高于当前行的去重记录的总行数,也就是说,如果出现像上图的数学科目中的重复的数据,就会去掉重复的数据。

2.查询每个班级中各个科目的前2名。

查询每个班级中各个科目的前2名只需要在第一步(查询本年级各个科目前2名的同学)的加上一个 class 班级的分区规则即可,查询的结果如下图所示:

select * from (

select sd.*, RANK() over(partition by subject, class order by score desc) as _rank from score_data sd

) tmp

where tmp._rank <=2

3. 查询每个班级中的总分排名前2名。

同理,在第二步(查询score_data表中每个班级中各个科目的前2名)的基础上再添加一个成绩的总和SUM(score)函数即可查询每个班级中的总分前两名。

select class,name,SUM(score) AS total_score,

RANK() over (PARTITION by class order by SUM(score) desc)

from score_data sd group by class,name



在这个指标的计算中,需要把聚合函数和排名函数结合起来使用,因为每个人的总成绩被拆分为了多个科目的和,所以需要在班级和科目的联合分组维度上进行聚合,把数据压缩到每人总分的颗粒度。

总结

窗口函数是 SQL 函数中非常强大的工具,尤其是在报表统计等场景领域。它们不仅能够简化复杂的数据计算和分析,还能提高查询效率和灵活性。窗口函数就像是数据库操作中最锋利的瑞士军刀,为我们提供了一种强大而精确的方式来处理数据。

扩展链接:

Spring Boot框架下实现Excel服务端导入导出

项目实战:在线报价采购系统(React +SpreadJS+Echarts)

Svelte 框架结合 SpreadJS 实现纯前端类 Excel 在线报表设计

高级SQL分析函数-窗口函数的更多相关文章

  1. Oracle SQL高级编程——分析函数(窗口函数)全面讲解

    Oracle SQL高级编程--分析函数(窗口函数)全面讲解 注:本文来源于:<Oracle SQL高级编程--分析函数(窗口函数)全面讲解> 概述 分析函数是以一定的方法在一个与当前行相 ...

  2. (4.34)sql server窗口函数

    关键词:sql server窗口函数,窗口函数,分析函数 如果分析函数不可用,那么可能是版本还不支持 Window Function 包含了 4 个大类.分别是: 1 - Rank Function ...

  3. 高级SQL特性

    SQL   SQL 必知必会·笔记<20>高级SQL特性 摘要: 约束(constraint)就是管理如何插入或处理数据库数据的规则.DBMS通过在数据库表上施加约束来实施引用完整性.1. ...

  4. [转]高级SQL注入:混淆和绕过

    ############# [0×00] – 简介[0×01] – 过滤规避(Mysql)[0x01a] – 绕过函数和关键词的过滤[0x01b] – 绕过正则表达式过滤[0×02] – 常见绕过技术 ...

  5. 总结SQL Server窗口函数的简单使用

    总结SQL Server窗口函数的简单使用 前言:我一直十分喜欢使用SQL Server2005/2008的窗口函数,排名函数ROW_NUMBER()尤甚.今天晚上我在查看SQL Server开发的相 ...

  6. DLA SQL分析函数:SQL语句审计与分析的利器

    1. 简介 Data Lake Analytics(https://www.aliyun.com/product/datalakeanalytics)最新release一组SQL内置函数,用来进行SQ ...

  7. Hive Sql的窗口函数

    date: 2019-08-30 11:02:37 updated: 2019-08-30 14:40:00 Hive Sql的窗口函数 1. count.sum.avg.max.min 以 sum ...

  8. 29.MySQL高级SQL语句

    MySQL高级SQL语句 目录 MySQL高级SQL语句 创建两个表 SELECT DISTINCT WHERE AND OR IN BETWEEN 通配符 LIKE ORDER BY 函数 数学函数 ...

  9. 第八章 SQL高级处理 8-1 窗口函数

    一.什么是窗口函数 窗口函数也称为LOAP函数.OnLine Analytical Processing的简称.意思是对数据库数据进行实时分析处理. 窗口函数就是为实现OLAP而添加的标准SQL功能. ...

  10. hive Spark SQL分析窗口函数

    Spark1.4发布,支持了窗口分析函数(window functions).在离线平台中,90%以上的离线分析任务都是使用Hive实现,其中必然会使用很多窗口分析函数,如果SparkSQL支持窗口分 ...

随机推荐

  1. 2022-11-10:写一个 bash 脚本以统计一个文本文件 words.txt 中每个单词出现的频率。 为了简单起见,你可以假设: words.txt只包括小写字母和 ‘ ‘ 。 每个单词只由小写

    2022-11-10:写一个 bash 脚本以统计一个文本文件 words.txt 中每个单词出现的频率. 为了简单起见,你可以假设: words.txt只包括小写字母和 ' ' . 每个单词只由小写 ...

  2. 2020-10-15:mysql的双1设置是什么?

    福哥答案2020-10-15:#福大大架构师每日一题# [答案来自知乎:](https://www.zhihu.com/question/425704691) 其实就是innodb_flush_log ...

  3. 2021-01-28:redis使用过程中的注意事项有哪些?

    福哥答案2021-01-28: [答案1:](https://italk.mashibing.com/question/detail/ques_00005101)1.使用key值前缀来作命名空间虽然说 ...

  4. 小程序使用wx.navigateTo无法跳转到加了tabBar的页面

    随着小程序的不断更新,发现目前的小程序版本使用navigator无法跳转到加了tabBar的页面:后来使用redirectTo进行跳转也不行:在刚开始也是纠结了好久一直找不到解决办法.最后从官方文档中 ...

  5. python基础:重新认识装饰器

    Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...

  6. CKS 考试题整理 (09)-日志审计 log audit

    Task 在cluster中启用审计日志.为此,请启用日志后端,并确保: 日志存储在 /var/log/kubernetes/audit-logs.txt 日志文件能保留 10 天 最多保留 2 个旧 ...

  7. C++容器(vector、deque、list、map)

    (1) vector:将元素置于一个动态数组中,可以随机存储元素(也就是用索引直接存取). 数组尾部添加或删除元素非常迅速.但在中部或头部就比较费时. *代码演示:* 取: at在下标越界时会抛出异常 ...

  8. docker-compose多服务器部署ELK

    多服务器构建ELK es使用1主2从,logstash转发,kibana展现,本文ELK版本使用7.16.1 如果单机测试,请查看docker-compose单服务器部署ELK es-master:1 ...

  9. 【linux命令】最强大的编辑器vim用法简介(基础篇)

    vim编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器.它主要分为命令令行模式.插入模式和底行模式这三种,下面主要介绍一下这三种模式最简单常用的用法. 一.命令 ...

  10. 前端Vue自定义带历史记录的搜索框组件searchBar 支持搜索输入框清空 搜索历史存储记录清除

    前端Vue自定义带历史记录的搜索框组件searchBar 支持搜索输入框清空 搜索历史存储记录清除,下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/p ...