排序函数:
排序函数的作用是基于一个结果集返回一个排序值。排序值就是一个数字,这个数字是典型的以1开始且自增长为1的行值。由排序函数来决定排序值。可以使唯一的对于当前结果集,或者某些行数据有相同的排序值。接下来介绍不同的排序函数以及如何使用这些函数。
示例数据:
语法:
1 | --select 函数名()over(order by 想排序的列名) from 表名 |
注:over()开窗函数用法在此文中不进行介绍
ROW_NUMBER()
定义:ROW_NUMBER()函数作用就是将select查询到的数据进行排序,每一条数据加一个序号,他不能用做于学生年龄的排名,一般多用于分页查询,因为在遇到相同年龄时序号依然会继续自增,而非并列的序号。
栗子:根据年龄降序排列学生
ROW_NUMBER()当遇到相同年龄时序号依然会自增
RANK()
定义:RANK()函数,顾名思义排名函数,可以对某一个字段进行排名,与ROW_NUMBER()不同,当存在相同年龄的学生时,ROW_NUMBER()会继续进行排序,他们的序号不相同,而Rank()则不一样,当出现相同的年龄时,他们的排名是一样的,并且会跳过已经占用的序号。
栗子:根据年龄降序排列学生
这里第五条数据突然从2号序号跳跃到5号序号,是因为上面已经有四位同学被排序过,按照已经被排序的数据条数就是5号
RANK()当遇到相同年龄时序号时序号不会自增,而是和相同年龄时的序号相同。同时当再次向下排序遇到不同年龄时,会根据已进行排序的条数来跳跃序号。
DENSE_RANK()
定义:DENSE_RANK()函数也是排名函数,和RANK()功能相似,也是对字段进行排名,那它和RANK()到底有什么不同那?
栗子:根据年龄降序排列学生
dense_rank函数的功能与rank函数类似,dense_rank函数在生成序号时是连续的,而rank函数生成的序号有可能不连续。dense_rank函数出现相同排名时,将不跳过相同排名号,rank值紧接上一次的rank值。在各个分组内,rank()是跳跃排序,有两个第一名时接下来就是第四名,dense_rank()是连续排序,有两个第一名时仍然跟着第二名。
NTILE()
定义:ntile函数可以对序号进行分组处理,将有序分区中的行分发到指定数目的组中。 各个组有编号,编号从一开始。 对于每一个行,ntile 将返回此行所属的组的编号。这就相当于将查询出来的记录集放到指定长度的数组中,每一个数组元素存放一定数量的记录。ntile函数为每条记录生成的序号就是这条记录所有的数组元素的索引(从1开始)。也可以将每一个分配记录的数组元素称为“桶”。ntile函数有一个参数,用来指定桶数。
将年龄降序并且平均分为四个桶(区)
ntile函数的分组依据(约定):
1、每组的记录数不能大于它上一组的记录数,即编号小的桶放的记录数不能小于编号大的桶。就是说,第1组中的记录数只能大于等于第2组及以后各组中的记录数。
2、所有组中的记录数要么都相同,要么从某一个记录较少的组(命名为X)开始后面所有组的记录数都与该组(X组)的记录数相同。也就是说,如果有个组,前三组的记录数都是9,而第四组的记录数是8,那么第五组和第六组的记录数也必须是8。
以上为四个排序函数的用法,最后一个可能不算排序,而是根据排序内容分桶,应用场景一般不为排序。而这些排序函数都依赖于over分窗函数,可以看到排序都是在它之中进行的,同时它也可以使用partition by排序的同时分组,类似于group by,也可以根据row和range进行开窗,但这里不过多解释。!
总结:
在使用排名函数的时候需要注意以下三点:
1、排名函数必须有 OVER 子句。
2、排名函数必须有包含 ORDER BY 的 OVER 子句。
3、分组内从1开始排序。