热情洋溢的春天呐
不错过春天❤️
也不错过你❤️

天暖了要照顾好自己
衣服也还要穿厚点
看起来胖胖的
让别人怕怕的
🌈🌈🌈
我们这次刷的题是分组排序的几种方法
~~~
先养眼,再看题
❤️
今天还是小姐姐

Question
分组排序
解之前我们已经提到分组排序row_number()但分组排序的家族中并不止这一个,这次主要说
row_number()
rank()
dense_rank()
ntile()

Function
详解
首先这几个都是分组排序,但最主要的区别就是
如果两个分数相同,排名是否同列以及排名是否相同。
但是这个方法仅在mysql8.0以后,hive或其他数据库支持


话不多说,直接上表
原始数据
| id | score |
| 1 | 90 |
| 2 | 100 |
| 3 | 80 |
| 4 | 100 |
| 5 | 90 |
期望数据
| id | score | row_ number | rank | dense_ rank | ntile |
| 2 | 100 | 1 | 1 | 1 | 1 |
| 4 | 100 | 2 | 1 | 1 | 1 |
| 1 | 90 | 3 | 3 | 2 | 2 |
| 5 | 90 | 4 | 3 | 2 | 2 |
| 3 | 80 | 5 | 5 | 3 | 3 |


从图中我们就可以发现
(不想看文字,下面有表总结)
row_number
如果并列但名次反而不相同,但是后续的名次是连续的
rank
如果并列则名次相同,但是后续的名次会不连续
dense_rank
如果并列则名次相同,但是后续的名次是连续的
ntile
如果并列则名次相同,后续的名次连续
我用下表来做个概述
| 方法 | 名次是否连续 | 名次是否并列 |
| row_number | yes | no |
| rank | no | yes |
| dense_rank | yes | yes |
| ntile | yes | yes |

row_number()
原理是先使用over子句中的排序语句对记录进行排序,然后再根据这个排序生成序号
select*,row_number() over (order by score desc) as rankfrom score;
查询结果如下
| id | score | rank |
| 2 | 100 | 1 |
| 4 | 100 | 2 |
| 1 | 90 | 3 |
| 5 | 90 | 4 |
| 3 | 80 | 5 |
使用场景
一般在工作中,常用分组排序做web程序的分页,然后我们指定查询范围。

rank()
作用效果和row_number()方法类似
但是支持并列排名,但排名名次可能不连续
select*,rank() over (order by score desc) as rankfrom score;
查询结果如下
| id | score | rank |
| 2 | 100 | 1 |
| 4 | 100 | 1 |
| 1 | 90 | 3 |
| 5 | 90 | 3 |
| 3 | 80 | 5 |

dense_rank()
作用效果和rank()方法类似,
不仅支持并列排名,而且排名也是连续的
select*,dense_rank() over (order by score) as rankfrom score;
查询结果如下
| id | score | rank |
| 2 | 100 | 1 |
| 4 | 100 | 1 |
| 1 | 90 | 2 |
| 5 | 90 | 2 |
| 3 | 80 | 3 |

ntile()
ntile()函数是最好理解
同时也是最不好理解的
结果既能够和其他函数相似
也能够有很大的区别。
select*,ntile(3) over (order by score desc) as rankfrom score;
查询结果如下
| id | score | rank |
| 2 | 100 | 1 |
| 4 | 100 | 1 |
| 1 | 90 | 2 |
| 5 | 90 | 2 |
| 3 | 80 | 3 |

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 : 第五组(十条)

Zongjie
总结
在使用分组排序函数的时候要注意以下三点:
1. 排名函数必须要有over子句
2. 排名函数必须要有order by的over子句
3. 分组内从1开始排序

Else
题外话
在此,根据分组排序暂时告一段落。
如果小伙伴还有其他的想法或问题也欢迎在评论区留言
让我们一起成长为老鸟,赚大钱!

郭大熊的公众号
个人博客 : www.guodaxiong.com
如果不曾见过阳光,我本可以忍受黑暗
Hi GuoDaXiong
我是狗子
祝你幸福






