排序函数

排序函数:

排序函数的作用是基于一个结果集返回一个排序值。排序值就是一个数字,这个数字是典型的以1开始且自增长为1的行值。由排序函数来决定排序值。可以使唯一的对于当前结果集,或者某些行数据有相同的排序值。接下来介绍不同的排序函数以及如何使用这些函数。

示例数据:

QQ截图20210312144133

语法:

1
2
3
4
--select 函数名()over(order by 想排序的列名) from 表名
--such as
select rank()over(partition by ssex order by sage desc)
from "student"

注:over()开窗函数用法在此文中不进行介绍

ROW_NUMBER()

定义:ROW_NUMBER()函数作用就是将select查询到的数据进行排序,每一条数据加一个序号,他不能用做于学生年龄的排名,一般多用于分页查询,因为在遇到相同年龄时序号依然会继续自增,而非并列的序号。

栗子:根据年龄降序排列学生

QQ截图20210312145034

ROW_NUMBER()当遇到相同年龄时序号依然会自增

RANK()

定义:RANK()函数,顾名思义排名函数,可以对某一个字段进行排名,与ROW_NUMBER()不同,当存在相同年龄的学生时,ROW_NUMBER()会继续进行排序,他们的序号不相同,而Rank()则不一样,当出现相同的年龄时,他们的排名是一样的,并且会跳过已经占用的序号。

栗子:根据年龄降序排列学生

QQ截图20210312145927

这里第五条数据突然从2号序号跳跃到5号序号,是因为上面已经有四位同学被排序过,按照已经被排序的数据条数就是5号

RANK()当遇到相同年龄时序号时序号不会自增,而是和相同年龄时的序号相同。同时当再次向下排序遇到不同年龄时,会根据已进行排序的条数来跳跃序号。

DENSE_RANK()

定义:DENSE_RANK()函数也是排名函数,和RANK()功能相似,也是对字段进行排名,那它和RANK()到底有什么不同那?

栗子:根据年龄降序排列学生

QQ截图20210312150624

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

NTILE()

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

QQ截图20210312160137

将年龄降序并且平均分为四个桶(区)

  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开始排序。

引自[Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)简介]

20200429013947.52ff80ba8cacf5780b8e9e93e02e02ef