排名函数是Sql Server2005新增的功用,下面简朴引见一下他们各自的用法和区分。我们新建一张Order表并增加一些初始数据轻易我们检察效果。
表构造和初始数据Sql
附上表构造和初始数据图:
一、ROW_NUMBER
row_number的用处的异常普遍,排序最好用他,平常能够用来完成web递次的分页,他会为查询出来的每一行纪录生成一个序号,顺次排序且不会反复,注重运用row_number函数时必须要用over子句挑选对某一列举行排序才生成序号。row_number用法实例:
select ROW_NUMBER() OVER(order by [SubTime] desc) as row_num,* from [Order]
查询效果以下图所示:
图中的row_num列就是row_number函数生成的序号列,其基本原理是先运用over子句中的排序语句对纪录举行排序,然后根据这个递次生成序号。over子句中的order by子句与SQL语句中的order by子句没有任何关系,这两处的order by 能够完整差别,如以下sql,over子句中根据SubTime降序分列,Sql语句中则按TotalPrice降序分列。
select ROW_NUMBER() OVER(order by [SubTime] desc) as row_num,* from [Order] order by [TotalPrice] desc
查询效果以下图所示:
应用row_number能够完成web递次的分页,我们来查询指定局限的表数据。例:根据定单提交时刻倒序分列猎取第三至第五条数据。
with orderSection as( select ROW_NUMBER() OVER(order by [SubTime] desc) rownum,* from [Order])select * from [orderSection] where rownum between 3 and 5 order by [SubTime] desc
查询效果以下图所示:
注重:在运用row_number完成分页时须要特别注重一点,over子句中的order by 要与Sql排序纪录中的order by 保持一致,不然获得的序号能够不是一连的。下面我们写一个例子来证明这一点,将上面Sql语句中的排序字段由SubTime改成TotalPrice。别的提一下,关于带有子查询和CTE的查询,子查询和CTE查询有序并不代表全部查询有序,除非显现指定了order by。
with orderSection as( select ROW_NUMBER() OVER(order by [SubTime] desc) rownum,* from [Order])select * from [orderSection] where rownum between 3 and 5 order by [TotalPrice] desc
查询效果以下图所示:
二、RANK
rank函数用于返回效果集的分区内每行的排名, 行的排名是相干行之前的排名数加一。简朴来讲rank函数就是对查询出来的纪录举行排名,与row_number函数差别的是,rank函数斟酌到了over子句中排序字段值雷同的状况,假如运用rank函数来生成序号,over子句中排序字段值雷同的序号是一样的,背面字段值不雷同的序号将跳过雷同的排名号排下一个,也就是相干行之前的排名数加一,能够明白为根据当前的纪录数生成序号,背面的纪录依此类推。能够我形貌的比较惨白,明白起来也比较费劲,我们直接上代码,rank函数的运用方法与row_number函数完整雷同。
select RANK() OVER(order by [UserId]) as rank,* from [Order]
查询效果以下图所示:
由上图能够看出,rank函数在举行排名时,统一组的序号是一样的,而背面的则是根据当前的纪录数顺次类推,图中第一、二条纪录的用户Id雷同,所以他们的序号是一样的,第三条纪录的序号则是3。
三、DENSE_RANK
dense_rank函数的功用与rank函数相似,dense_rank函数在生成序号时是一连的,而rank函数生成的序号有能够不一连。dense_rank函数涌现雷同排名时,将不跳过雷同排名号,rank值紧接上一次的rank值。在各个分组内,rank()是腾跃排序,有两个第一名时接下来就是第四名,dense_rank()是一连排序,有两个第一名时依然随着第二名。将上面的Sql语句改由dense_rank函数来完成。
select DENSE_RANK() OVER(order by [UserId]) as den_rank,* from [Order]
查询效果以下图所示:
图中第一、二条纪录的用户Id雷同,所以他们的序号是一样的,第三条纪录的序号紧接上一个的序号,所认为2不为3,背面的依此类推。
四、NTILE
ntile函数能够对序号举行分组处置惩罚,将有序分区中的行分发到指定数目的组中。 各个组有编号,编号从一最先。 关于每个行,ntile 将返回此行所属的组的编号。这就相当于将查询出来的纪录集放到指定长度的数组中,每个数组元素寄存肯定数目的纪录。ntile函数为每条纪录生成的序号就是这条纪录一切的数组元素的索引(从1最先)。也能够将每个分派纪录的数组元素称为“桶”。ntile函数有一个参数,用来指定桶数。下面的SQL语句运用ntile函数对Order表举行了装桶处置惩罚:
select NTILE(4) OVER(order by [SubTime] desc) as ntile,* from [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。
根据上面的两个商定,能够得出以下的算法:
//mod示意取余,p示意取整.if(纪录总数 mod 桶数==0) { recordCount=纪录总数 p 桶数; //将每桶的纪录数都设为recordCount.}else{ recordCount1=纪录总数 p 桶数+1; int n=1;//n示意桶中纪录数为recordCount1的最大桶数. m=recordCount1*n; while(((纪录总数-m) mod (桶数- n)) !=0) { n++; m=recordCount1*n; } recordCount2=(纪录总数-m) p (桶数-n); //将前n个桶的纪录数设为recordCount1. //将n+1个至背面一切桶的纪录数设为recordCount2.}
根据上面的算法,假如总纪录数为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。
select ntile,COUNT([ID]) recordCount from ( select NTILE(4) OVER(order by [SubTime] desc) as ntile,* from [Order]) as tgroup by t.ntile
运转Sql,分组效果如图:
比对算法与Sql Server的分组效果是一致的,申明算法没错。:)
总结:
在运用排名函数的时刻须要注重以下三点:
1、排名函数必需有 OVER 子句。
2、排名函数必需有包括 ORDER BY 的 OVER 子句。
3、分组内从1最先排序。
本文解说了Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)相干学问,更多相干内容请关注ki4网。
相干引荐:
Mysql经常使用基准测试东西
Mysql函数 的相干解说
SQLLite相干内容
以上就是Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)简介的细致内容,更多请关注ki4网别的相干文章!