分组排序
最主要的区别就是如果两个分数相同,排名是否同列以及排名是否相同。
这个方法仅在mysql8.0以后,hive或其他数据库支持
直接看图:原始表
原表如上,想要的结果如下
从图中可以发现:
- row_number函数:如果并列但名次反而不相同,但是后续的名次是连续的
- rank函数:如果并列则名次相同,但是后续的名次会不连续
- dense_rank函数:如果并列则名次相同,但是后续的名次是连续的
- ntile函数:如果并列则名次相同,后续的名次连续
row_number
基本原理是先使用over子句中的排序语句对记录进行排序,然后再根据这个排序生成序号。
select *, row_number() over (order by score desc) as rank
from score;
查询结果如下
一般在工作中,常用分组排序做web程序的分页,然后我们指定查询范围。
row_number()进阶
rank
作用效果和row_number()方法类似,但是支持并列排名,但排名名次可能不连续。
select *, rank() over (order by score desc) as rank
from score;
查询结果如下
dense_rank
作用效果和rank()方法类似,不仅支持并列排名,而且排名也是连续的
select *, dense_rank() over (order by score) as rank
from score;
查询结果如下
ntile
ntile()函数是最好理解,同时也是最不好理解的。结果既能够和其他函数相似,也能够有很大的区别。
select *, ntile(3) over (order by score desc) as rank
from score;
查询结果如下
ntile函数可以对序号进行分组处理,类似于hive的分桶处理:
ntile函数的分桶依据:
1、每组的记录数不能大于它上一组的记录数,即编号小的桶放的记录数不能小于编号大的桶。也就是说,第1组中的记录数只能大于等于第2组及以后各组中的记录数。
2、所有组中的记录数要么都相同,要么从某一个记录较少的组(命名为X)开始后面所有组的记录数都与该组(X组)的记录数相同。也就是说,如果有个组,前三组的记录数都是9,而第四组的记录数是8,那么第五组和第六组的记录数也必须是8。
举个栗子
如果是50条,那么就是
1-10 : 第一组 (十条)
11-20 : 第二组(十条)
21-30 : 第三组(十条)
31-40 : 第四组(十条)
41-50 : 第五组(十条)
如果是51条,那么就是
1-11 : 第一组(十一条)
12-21 : 第二组(十条)
22-31 : 第三组(十条)
32-41 : 第四组(十条)
42-51 : 第五组(十条)
总结
在使用分组排序函数的时候要注意以下三点:
- 排名函数必须要有over子句
- 排名函数必须要有order by的over子句
- 分组内从1开始排序