分享好友 最新动态首页 最新动态分类 切换频道
转:Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)简介
2024-12-27 14:34

https://www.cnblogs.com/52xf/p/4209211.html

转:Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)简介

 

 

  附上表结构和初始数据图

用法

:语法(用法)
     rank() over([partition by col1] order by col2)
     dense_rank() over([partition by col1] order by col2)
     row_number() over([partition by col1] order by col2)
     其中[partition by col1]可省略。

 

一、ROW_NUMBER

  row_number的用途的非常广泛,排序最好用他,一般可以用来实现web程序的分页,他会为查询出来的每一行记录生成一个序号,依次排序且不会重复,注意使用row_number函数时必须要用over子句选择对某一列进行排序才能生成序号。row_number用法实例:

 

 

 

  查询结果如下图所示

  图中的row_num列就是row_number函数生成的序号列,其基本原理是先使用over子句中的排序语句对记录进行排序,然后按照这个顺序生成序号。over子句中的order by子句与SQL语句中的order by子句没有任何关系,这两处的order by 可以完全不同,如以下sql,over子句中根据SubTime降序排列,Sql语句中则按TotalPrice降序排列。

 

  查询结果如下图所示

  利用row_number可以实现web程序的分页,我们来查询指定范围的表数据。例:根据订单提交时间倒序排列获取第三至第五条数据。

 

  查询结果如下图所示

  注意:在使用row_number实现分页时需要特别注意一点,over子句中的order by 要与Sql排序记录中的order by 保持一致,否则得到的序号可能不是连续的。下面我们写一个例子来证实这一点,将上面Sql语句中的排序字段由SubTime改为TotalPrice。另外提一下,对于带有子查询和CTE的查询,子查询和CTE查询有序并不代表整个查询有序,除非显示指定了order by。

 

  查询结果如下图所示

  

二、RANK

  rank函数用于返回结果集的分区内每行的排名, 行的排名是相关行之前的排名数加一。简单来说rank函数就是对查询出来的记录进行排名,与row_number函数不同的是,rank函数考虑到了over子句中排序字段值相同的情况,如果使用rank函数来生成序号,over子句中排序字段值相同的序号是一样的,后面字段值不相同的序号将跳过相同的排名号排下一个,也就是相关行之前的排名数加一,可以理解为根据当前的记录数生成序号,后面的记录依此类推。可能我描述的比较苍白,理解起来也比较吃力,我们直接上代码,rank函数的使用方法与row_number函数完全相同。

 

  查询结果如下图所示

  由上图可以看出,rank函数在进行排名时,同一组的序号是一样的,而后面的则是根据当前的记录数依次类推,图中第一、二条记录的用户Id相同,所以他们的序号是一样的,第三条记录的序号则是3。  

 

三、DENSE_RANK

  dense_rank函数的功能与rank函数类似,dense_rank函数在生成序号时是连续的,而rank函数生成的序号有可能不连续。dense_rank函数出现相同排名时,将不跳过相同排名号,rank值紧接上一次的rank值。在各个分组内,rank()是跳跃排序,有两个第一名时接下来就是第四名,dense_rank()是连续排序,有两个第一名时仍然跟着第二名。将上面的Sql语句改由dense_rank函数来实现。

 

  查询结果如下图所示

  图中第一、二条记录的用户Id相同,所以他们的序号是一样的,第三条记录的序号紧接上一个的序号,所以为2不为3,后面的依此类推。

四、NTILE

  ntile函数可以对序号进行分组处理,将有序分区中的行分发到指定数目的组中。 各个组有编号,编号从一开始。 对于每一个行,ntile 将返回此行所属的组的编号。这就相当于将查询出来的记录集放到指定长度的数组中,每一个数组元素存放一定数量的记录。ntile函数为每条记录生成的序号就是这条记录所有的数组元素的索引(从1开始)。也可以将每一个分配记录的数组元素称为“桶”。ntile函数有一个参数,用来指定桶数。下面的SQL语句使用ntile函数对Order表进行了装桶处理

 

  查询结果如下图所示

  Order表的总记录数是6条,而上面的Sql语句ntile函数指定的组数是4,那么Sql Server2005是怎么来决定每一组应该分多少条记录呢?这里我们就需要了解ntile函数的分组依据(约定)。

  ntile函数的分组依据(约定

  1、每组的记录数不能大于它上一组的记录数,即编号小的桶放的记录数不能小于编号大的桶。也就是说,第1组中的记录数只能大于等于第2组及以后各组中的记录数。

  2、所有组中的记录数要么都相同,要么从某一个记录较少的组(命名为X)开始后面所有组的记录数都与该组(X组)的记录数相同。也就是说,如果有个组,前三组的记录数都是9,而第四组的记录数是8,那么第五组和第六组的记录数也必须是8。

  这里对约定2进行详细说明一下,以便于更好的理解。

  首先系统会去检查能不能对所有满足条件的记录进行平均分组,若能则直接平均分配就完成分组了;若不能,则会先分出一个组,这个组分多少条记录呢?就是 (总记录数/总组数+1 条,之所以分配 (总记录数/总组数+1 条是因为当不能进行平均分组时,总记录数%总组数肯定是有余的,又因为分组约定1,所以先分出去的组需要+1条。

  分完之后系统会继续去比较余下的记录数和未分配的组数能不能进行平均分配,若能,则平均分配余下的记录;若不能,则再分出去一组,这个组的记录数也是(总记录数/总组数+1条。

  然后系统继续去比较余下的记录数和未分配的组数能不能进行平均分配,若能,则平均分配余下的记录;若还是不能,则再分配出去一组,继续比较余下的......这样一直进行下去,直至分组完成。

  举个例子,将51条记录分配成5组,51%5==1不能平均分配,则先分出去一组(51/5+1=11条记录,然后比较余下的 51-11=40 条记录能否平均分配给未分配的4组,能平均分配,则剩下的4组,每组各40/4=10 条记录,分配完成,分配结果为:11,10,10,10,10,晓菜鸟我开始就错误的以为他会分配成 11,11,11,11,7。

  根据上面的两个约定,可以得出如下的算法

 
 

  

  根据上面的算法,如果总记录数为59,总组数为5,则 n=4 , recordCount1=12 , recordCount2=11,分组结果为 :12,12,12,12,11。

  如果总记录数为53,总组数为5,则 n=3 , recordCount1=11 , recordCount2=10,分组结果为:11,11,11,10,10。

  就拿上面的例子来说,总记录数为6,总组数为4,通过算法得到 n=2 , recordCount1=2 , recordCount2=1,分组结果为:2,2,1,1。

 

  运行Sql,分组结果如图

  比对算法与Sql Server的分组结果是一致的,说明算法没错。:)

 

总结

在使用排名函数的时候需要注意以下三点

  1、排名函数必须有 OVER 子句。

  2、排名函数必须有包含 ORDER BY 的 OVER 子句。

  3、分组内从1开始排序。

 

感谢

  在博文的最后我要感谢园友 海岸线,他写的 SQL2005四个排名函数(row_number、rank、dense_rank和ntile)的比较 对我帮助很大,非常感谢

最新文章
WordPress新手视频教程10:常用必备插件Plugin推荐和安装
通过合理使用WordPress的免费和付费插件,能够帮你的网站增加功能和提升谷歌上的SEO排名。 但是很多WordPress新手并不是很了解什么是WordPress插件,或者说不知道应该安装哪些WordPress插件。 在本章中,我们将研究如何在WordPress中安装插
用AI画美女:一键生成超高清美女写真,体验最新科技魅力!
限时免费,点击体验最近超火的AI生图神器,坐拥3000美女的大男主就是你! https://ai.sohu.com/pc/generate/textToImg?_trans_=030001_yljdaimn 在这个炫酷的科技时代,AI生成的艺术作品已然成为了社交媒体上的热话题。想象一下,宝子们,
鲁兆最新动态与观点解析,鲁兆最新动态及观点深度解析
摘要:鲁兆的最新动态显示他依然活跃在学术界和社会领域。他近期发表的观点解析,关注社会热点问题,对经济发展趋势进行深入剖析,并强调科技创新的重要性。他认为,在全球化背景下,应更加注重开放合作,推动科技进步,同时关注社会公平与
萧山烹饪学校排名(萧山烹饪学校排名优化)
:探寻最佳烹饪教育之地在美食文化日益繁荣的今天,烹饪技能的学习与提升成为众多热爱美食人士的追求。作为浙江省杭州市的重要区域,萧山区汇聚了多所知名的烹饪学校。这些学校以各自独特的优势和教学特色,在培养烹饪人才方面发挥着重要作
搜狗如何快速收录 搜狗加速收录秘籍,新媒体内容秒上搜索榜
搜狗如何快速收录文章:专业策略与实操指南在数字时代,搜索引擎优化(SEO)已成为网站获取流量、提升品牌影响力的关键手段之一搜狗搜索引擎,作为中国互联网领域的重要参与者,其收录速度和排名机制对于网站而言至关重要本文将深入探讨如
百度seo是什么意思?
百度seo是什么意思?百度seo指的是采用有效的方式提升网站在百度的搜索结果,主要的表现就是让网站出现在百度的前几页,要是可以出现在首页前几条的话,那将是最为完美的事情。因为网站有这样的排名,才能实现自身产品及网站信息的最大化曝
知乎精选:无条件下款的网贷有哪些-指数基金纳入个人养老金基金名录有何意义? 易方达基金:有助于构建“长钱长投”生态
  《通知》规定,在现有理财产品、储蓄存款、商业养老保险和公募基金产品基础上,将国债、特定养老储蓄、指数基金纳入个人养老金产品范围。金融机构要做好个人养老金产品资产配置公示等工作,依法依规开展投资咨询服务,探索开展默认投资
搜狗输入法医生版 v1.1 免费安装版
搜狗输入法医生版是一款十分不错的专门为从事医疗职业的群体而打造的智能输入法。软件内包含医疗词库、超级联想、简约风格、医生定制等特色,本站提供的是该软件的安装版本,欢迎需要的朋友前来本站下载使用。医疗词库针对医生群体专业词汇
百度蜘蛛池价格:蜘蛛池创建教程图片大全,轻松搭建高效SEO工具
百度蜘蛛池价格合理,提供详细创建教程及图片,助您轻松搭建高效SEO工具。本文目录导读:什么是蜘蛛池?蜘蛛池创建教程蜘蛛池创建教程图片大全随着互联网的快速发展,搜索引擎优化(SEO)成为了许多企业和个人获取流量、提高品牌知名度的重
河南玄同智能科技申请边缘分布场景下的状态应用的全链路监控专利,具备延迟低、数据安全性强和系统响应速度快的优点
金融界2024年12月18日消息,国家知识产权局信息显示,河南玄同智能科技有限公司申请一项名为“边缘分布场景下的状态应用的全链路监控方法和系统”的专利,公开号CN 119127614 A,申请日期为2024年9月。专利摘要显示,本发明公开了一种边缘
相关文章
推荐文章
发表评论
0评