1、为省时间,给同学们先看结论:
- row_number()排序相同时不会重复,会根据顺序排序;排名举例:1、2、3、4;
- rank()排序相同时会重复,总数不变;排名举例:1、2、2、4;
- dense_rank()排序相同时会重复,总数会减少;排名举例:1、2、2、3;
- ntile()确认最高排名,最高排名需要小于等于总数;排名举例ntile(N):1、2、3...N;
- partition by先分组,再进行组内排名;
2、 背景交代:
- 教学数据库为Oracle数据库;
- 为方便教学创建一张学生分数表student_score,并插入数据;
CREATE TABLE ESHARE_DW.student_score (
id VARCHAR ( 10 ) NOT NULL,
name VARCHAR ( 20 ) NOT NULL,
score NUMBER ( 32 ) NOT NULL );
insert into ESHARE_DW.student_score(id,name,score) values(1,'赵子龙',95);
insert into ESHARE_DW.student_score(id,name,score) values(2,'马超',80);
insert into ESHARE_DW.student_score(id,name,score) values(3,'关羽',95);
insert into ESHARE_DW.student_score(id,name,score) values(1,'诸葛亮',100);
insert into ESHARE_DW.student_score(id,name,score) values(2,'阿斗',60);
insert into ESHARE_DW.student_score(id,name,score) values(3,'刘备',80);
SELECT * FROM student_score
数据如下:
![](https://i-blog.csdnimg.cn/blog_migrate/e75c7b68216bc5e21ecee7d397bf57f8.png)
3.1、 ROW_NUMBER (连续排名)
功能
- 一般可以用来实现分页;
- 他会为查询出来的每一行记录生成一个序号,依次排序且不会重复;
- 注意使用row_number函数时必须要用over子句选择对某一列进行排序才能生成序号;
用法:
SELECT
ss.ID,
ss.NAME,
ss.SCORE,
ROW_NUMBER ( ) OVER ( ORDER BY ss.SCORE DESC ) ROW_NUMBER
FROM
STUDENT_SCORE ss
结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/a8e876500c1d19eff2e662eaa5fb33f0.png)
3.2、 rank() (并列跳跃排名)
功能:
- 对于同值元组,排名序号相同。
- 但所有相同的元组各自为组,即对别的元组来说影响都是多元的。
用法:
SELECT
ss.ID,
ss.NAME,
ss.SCORE,
RANK ( ) OVER ( ORDER BY ss.SCORE DESC ) RANK
FROM
STUDENT_SCORE ss;
结果:
![](https://i-blog.csdnimg.cn/blog_migrate/2ed9cd0891463ed8337edf925d7c69a4.png)
3.3 DENSE_RANK (并列连续排名)
功能:
- 对于同值元组,排名序号相同。
- 且所有相同的元组算作一组,即对别的元组来说影响都是一元的。
用法:
SELECT
ss.ID,
ss.NAME,
ss.SCORE,
dense_rank() OVER ( ORDER BY ss.SCORE DESC ) dense_rank
FROM
STUDENT_SCORE ss;
结果:
![](https://i-blog.csdnimg.cn/blog_migrate/ba733a2efaf61d035508e074ebe3f6ed.png)
3.4 NTILE() (分组排名)
功能:
- 按指定列将所有记录分成指定个数的组,每一组序号相同,但组内元组指定的列可能不同;
- 相当于按指定列先排序,再按长度截断分组;
- NTILE() 括号内为长度参数;
用法:
SELECT
ss.ID,
ss.NAME,
ss.SCORE,
NTILE(4) OVER ( ORDER BY ss.SCORE DESC ) NTILE
FROM
STUDENT_SCORE ss;
结果:
![](https://i-blog.csdnimg.cn/blog_migrate/be6a66fba835ed5fc3893f4f48d37523.png)
3.5 PARTITION BY(组内排序)
功能:
- 按照某字段分组;
- 并在组内进行row_number()、 rank()、 dense_rank()、NTILE()排序;
用法:
SELECT
ss.ID,
ss.NAME,
ss.SCORE,
RANK() OVER ( partition by ID ORDER BY ss.SCORE DESC ) RANK_PARTITION
FROM
STUDENT_SCORE ss;
结果:
![](https://i-blog.csdnimg.cn/blog_migrate/1cf71edd5f40a9c72b8580985260f2af.png)