当前位置: 首页 > news >正文

MariaDB Window Functions窗口函数分组取TOP N记录

窗口函数在MariaDB10.2版本里实现,其简化了复杂SQL的撰写,提高了可读性。

在某些方面,窗口函数类似于聚集函数, 但它不像聚集函数那样每组只返回一个值,窗口函数可以为每组返回多个值。

作为一种高级查询功能,解释起来并非易事。提供窗口函数介绍的最佳方法是通过示例,让我们看看窗口函数实现分组取TOP N记录。


表结构

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `SName` varchar(100) DEFAULT NULL COMMENT '姓名',
  `ClsNo` varchar(100) DEFAULT NULL COMMENT '班级',
  `Score` int(11) DEFAULT NULL COMMENT '分数',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
insert into `student`(`id`,`SName`,`ClsNo`,`Score`) values 
(1,'AAAA','C1',67),(2,'BBBB','C1',55),(3,'CCCC','C1',67),(4,'DDDD','C1',65),
(5,'EEEE','C1',95),(6,'FFFF','C2',57),(7,'GGGG','C2',87),(8,'HHHH','C2',74),
(9,'IIII','C2',52),(10,'JJJJ','C2',81),(11,'KKKK','C2',67),(12,'LLLL','C2',66),
(13,'MMMM','C2',63),(14,'NNNN','C3',99),(15,'OOOO','C3',50),(16,'PPPP','C3',59),
(17,'QQQQ','C3',66),(18,'RRRR','C3',76),(19,'SSSS','C3',50),(20,'TTTT','C3',50),
(21,'UUUU','C3',64),(22,'VVVV','C3',74);

查询结果

图片.png


现在取出各班前三名

SELECT SName,ClsNo,Score,
dense_rank() OVER (PARTITION BY ClsNo ORDER BY Score DESC) AS top3
FROM student;

使用窗口函数需要OVER关键字。 dense_rank()是一个特殊的排名函数,只能作为“窗口函数”使用,不能在没有OVER子句的情况下使用。

OVER子句支持一个名为PARTITION BY的关键字,它与GROUP BY的工作方式非常相似。 使用PARTITION BY,我们将按照班级分组,并单独计算排名行号。

图片.png

我们可以看到每个班级都有一个单独的排名顺序。


窗口函数的计算发生在WHERE,GROUP BY和HAVING子句完成之后,在ORDER BY之前。固这里需要外包一层派生表得到最终排名结果。

SELECT * FROM
(SELECT SName,ClsNo,Score, dense_rank() OVER (PARTITION BY ClsNo ORDER BY Score DESC) AS top3 FROM student) AS tmp
WHERE tmp.top3 <=3 ORDER BY tmp.ClsNO ASC,tmp.Score DESC;

图片.png

通过窗口函数,非常轻松的实现分析需求,而使用传统的方法,会非常复杂,SQL理解起来也很困难。

例:

SELECT a.id,a.SName,a.ClsNo,a.Score FROM student a 
LEFT JOIN student b ON a.ClsNo=b.ClsNo
AND a.Score<b.Score 
GROUP BY a.id,a.SName,a.ClsNo,a.Score HAVING COUNT(b.id)<3
ORDER BY a.ClsNo,a.Score DESC;

图片.png


参考:

https://mariadb.com/kb/en/library/window-functions-overview/

https://blog.csdn.net/acmain_chm/article/details/4126306




相关文章:

  • Linux职场解读:如何进入500强企业?
  • 拥抱电商,语音助手正在成为“方便之王”
  • 第0次作业
  • Linux Bash Shell字符串抽取、按列合并和格式化输出
  • TCP/IP学习笔记(7)-广播,多播IGMP协议
  • 【编译打包】sphinx-for-chinese-2.2.1-r4311.el6.src.rpm
  • 缓冲区溢出漏洞实验
  • MSQL基本增删改语句汇总练习
  • Jsp/Servlet:小结图片操作的一些代码
  • 十:Application Lifecycle Management in Visual Studio 2008 Team Foundation Server 2008
  • it之家
  • 天气预报代码调用
  • Java静态方法和实例方法 java中的数组作为形参传入
  • [CodeForces-759D]Bacterial Melee
  • MongoDB lsm降低 disk lantency
  • 分享一款快速APP功能测试工具
  • 4个实用的微服务测试策略
  • Babel配置的不完全指南
  • input实现文字超出省略号功能
  • Java 内存分配及垃圾回收机制初探
  • JavaScript设计模式与开发实践系列之策略模式
  • mysql常用命令汇总
  • PHP变量
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • vue的全局变量和全局拦截请求器
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 对超线程几个不同角度的解释
  • 工作手记之html2canvas使用概述
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 基于axios的vue插件,让http请求更简单
  • 基于web的全景—— Pannellum小试
  • 老板让我十分钟上手nx-admin
  • 前端之React实战:创建跨平台的项目架构
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 一道面试题引发的“血案”
  • 用jquery写贪吃蛇
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​secrets --- 生成管理密码的安全随机数​
  • #《AI中文版》V3 第 1 章 概述
  • #pragam once 和 #ifndef 预编译头
  • (1)常见O(n^2)排序算法解析
  • (31)对象的克隆
  • (第一天)包装对象、作用域、创建对象
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (九)One-Wire总线-DS18B20
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .NET CF命令行调试器MDbg入门(三) 进程控制
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .Net Memory Profiler的使用举例
  • .net wcf memory gates checking failed