实用sql技巧,开窗函数

   日期:2024-12-29    作者:gubida 移动:http://mip.riyuangf.com/mobile/quote/80040.html

最近在牛客解sql题目时,经常有一类题目要求对表中的某一列进行排序

实用sql技巧,开窗函数

在查看提供的题解时经常看到使用开窗函数的解决方案

虽然不用开窗函数也能通过子查询的方式获取正确答案,但是

比较复杂难以理解

所以很有必要学习

第1行表示id为1的用户通过了4个题目;

第6行表示id为6的用户通过了4个题目;

思考

​ 题目只有一张表,两个字段,看似很简单

​ 如果没有t_rank要组合的话只需要

 

​ 但我们现在需要组合出t_rank,

在不使用开窗函数情况下的解题思路

我开始时想通过聚合函数构造一个字段,但事情并不简单,需要得出排名并非能够通过一个聚合解决

需要使用通过子查询来得出排名的值

具体实现(参考该题的第一名的解答

要得到通过题目的排名,比如你通过了8分,,你同学a也通过了8分,找到大于等于你的成绩,一个9分,一个8分,一个8分,去重复,就一个9,一个8,count一下总数,第2名,如果有三个同学通过了7个呢,同理,9,8,8,7,7,7 后面比这个少的,已经死在了筛选条件,去重,9,8,7,count=3

确实,如果我们得了10分,没有人超过我们,那么找到大于等于我的成绩,及10,count一下就是1了,即第一名

故总结为

 

如此,加上最初的那句简单sql,即可以得出本题的一种答案

 
 

显然这个逻辑还是有一点复杂的

下面先显示使用开窗函数的答案

 

这个答案也可以达到一样的效果

这个sql语句则简洁很多,现在需要理解的就只是这个开窗函数了

前言:老版本的mysql并不支持开窗函数,如需使用请使用mysql8以上的版本

开窗函数的定义

 

开窗函数与聚合函数

 

开窗函数的使用

​ 从开窗函数的定义中,可以了解到开窗函数比普通的聚合函数更加的灵活,功能也更加强大。但并不是很好理解,那么先从它的使用开始吧

 

开窗函数的一个概念是当前行,当前行属于某个窗口,窗口由
over关键字用来指定函数执行的窗口范围,如果后面括号中什么都不写,则意味着窗口包含满足where条件的所有行,开窗函数基于所有行进行计算;如果不为空,则有三个参数来设置窗口

partition by子句

按照指定字段进行分区,两个分区由边界分隔,开窗函数在不同的分区内分别执行,在跨越分区边界时重新初始化。

order by子句

按照指定字段进行排序,开窗函数将按照排序后的记录顺序进行编号。可以和partition by子句配合使用,也可以单独使用。

frame子句

当前分区的一个子集,用来定义子集的规则,通常用来作为滑动窗口使用。

常用的开窗函数

这里直接在官网查了一下,网址如下MySQL :: MySQL 8.0 Reference Manual :: 12.21.1 Window Function Descriptions

以上大部分函数的使用效果用例都可以在上面的官网中看到示例

下面是在实际中的使用

如上面的原题

​ 分析其开窗函数的含义

 

突然发现了新东西貌似比较有趣,明天接着更

构造一张表,在其中插入一些信息

 
 
 

我们先利用几个开窗函数中的排名函数来测试一下

 
 
 

再测试一下计算累计分布值,和Bucket number的开窗函数

我先查一下bucket number,发现网上并没有这个东西的准确信息,只能在官网里看其定义了

以上表的数据测试一下

 

Window关键字的用法可以参考

MySQL8中的关键字window与窗口函数_程序员先森的博客-CSDN博客

测试

 
 
 

通过partition by 关键字确定开窗函数的分区

 
 
 

官网的介绍:MySQL :: MySQL 8.0 Reference Manual :: 12.21.3 Window Function Frame Specification

与窗口函数一起使用的窗口的定义可以包括Frame子句。 Frame是当前分区的子集,Frame子句指定如何定义子集。

Frame是相对于当前行确定的,这使得Frame能够根据当前行在其分区内的位置在分区内移动。

例子: 通过将一个框架定义为从分区开始到当前行的所有行,您可以计算每行的运行总数。

​ 通过将框架定义为在当前行的任一侧扩展 N 行,您可以计算滚动平均值。

官网的介绍很复杂,这里有一篇更优秀的文章可以参考


特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。


举报收藏 0评论 0
0相关评论
相关最新动态
推荐最新动态
点击排行
{
网站首页  |  关于我们  |  联系方式  |  使用协议  |  隐私政策  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  鄂ICP备2020018471号