首页 > 其他分享 >如何利用窗口函数实现精确排名计算?

如何利用窗口函数实现精确排名计算?

时间:2024-06-24 09:22:49浏览次数:25  
标签:班级 窗口 函数 RANK 查询 score 精确 科目

前言

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 函数中非常强大的工具,尤其是在报表统计等场景领域。它们不仅能够简化复杂的数据计算和分析,还能提高查询效率和灵活性。

扩展链接:

窗口函数运算法则大盘点

标签:班级,窗口,函数,RANK,查询,score,精确,科目
From: https://www.cnblogs.com/powertoolsteam/p/18264341

相关文章

  • isNaN 和 Number.isNaN 函数的区别?
    对于可以被Number转换为数值的值x,那么isNaN(x)就是false如果不可以被Number转换为数值的值y,那么isNaN(y)就是true//Number.isNaN与isNaN最的区别是,Number.isNaN不存在类型转换的行为。console.log(isNaN('测试'))//trueconsole.log(Number.isNaN('测试'))//false上面......
  • 【优化分配】粒子群算法求解机组负荷分配优化问题(目标函数:最优成本)【含Matlab源码 478
    ✅博主简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,Matlab项目合作可私信。......
  • pyqt5创建主窗口(介绍窗口类型)
    创建主窗口(介绍窗口类型)我们用QMainWindow主窗口代码来创建UIQMainWindow.setWindowTitle(字符串),设置窗口标题QMainWindow.resize(800,400),设置窗口尺寸QMainWindow.statusBar(),获取状态栏对象QMainWindow.showMessage('停留5秒消息',5000)QApplication.setWindowIcon(QIco......
  • 【操作系统】信号Signal超详解|捕捉函数
    ......
  • API-定时器-间歇函数
    学习目标:掌握定时器-间歇函数学习内容:定时器-间歇函数案例定时器-间歇函数:网页中经常需要一种功能:每隔一段时间需要`自动`执行一段代码,不需要我们手动去触发。例如:网页中的倒计时。要实现这种需求,需要定时器函数。定时器函数有两种,我们先讲间歇函数。开启定时......
  • 函数与模块
                     ......
  • C语言之IO流函数
    目录1IO函数1.1错误函数1.1.1检测流上的错误函数ferror1.1.2复位错误标志函数clearerr1.2结束函数1.2.1检测文件结束符函数feof1.2.2清除文件缓冲区函数fflush1.3处理文件函数1.3.1文件的打开与关闭函数fopen,fclose1.3.2替换文件中数据流函数freopen1.3.3文件指针定......
  • Python进阶学习笔记-函数篇
    函数的特殊参数#/前的参数只能是位置参数,*后面的只能是关键字参数,之间的不限参数类型deffunc(a,b,/,c,*,d,e):print(a,b,c,d,e)func(1,2,3,d=4,e=5)func(1,2,c=3,d=4,e=5)#a,b不能以关键字形式传参,d,e只能以关键字参数传参#可变参数*argsdef......
  • Java学习 - MySQL存储过程、函数和触发器练习实例
    存储过程存储过程是什么存储过程是一组已经编译好的SQL语句存储过程优点有什么安全性能高提高代码复用性创建存储过程的语法DELIMITER$#不能加分号CREATEPROCEDURE存储过程名(IN|OUT|INOUT参数名参数类型)BEGIN存储过程语句块END;$DELIMIT......
  • C语言之字符处理函数
    目录1字符处理函数1.1检查型函数1.1.1检查字符是字母或数字isalnum1.1.2检查字符是否是字母isalpha1.1.3检查字符是否是ASCII码isascii1.1.4检查字符是否是控制字符iscntrl1.1.5检查字符是否是数字字符isdigit1.1.6检查字符是否是可打印字符(不含空格)isgraph1.1.7检查字......