astak16/blog-mysql

序号函数 row_number()、 rank()、 dense_rank()

Opened this issue · 0 comments

create table sequence (id int, name varchar(10), age int);

insert into sequence values
(1, '张三', 19),
(2, '李四', 20),
(3, '王五', 30),
(4, '赵六', 24),
(5, '小红', 19);

使用 select * from sequence 查询出来结果,是默认排序的,如下图:

id name age
1 张三 19
2 李四 20
3 王五 30
4 赵六 24
5 小红 19

下面使用分别使用 row_number()rank()dense_rank() 排序,看看是什么效果。

row_number() 根据顺序排序,不会重复

age 进行升序排列,需要结合 over() 来使用

select *, row_number() over(order by age) as 排名 from sequence;

如图所示:

id name age 排名
1 张三 19 1
5 小红 19 2
2 李四 20 3
4 赵六 24 4
3 王五 30 5

查询出来的结果是按照 age 进行升序排列,不重复, age 相同的数据按照它的默认顺序进行展示,如果想自定义相同 age 的顺序,和 order by 字段使用的方法一致

rank() 排序相同时,会重复

age 进行升序排列,需要结合 over() 来使用

select *, rank() over(order by age) as 排名 from sequence;

如图所示:

id name age 排名
1 张三 19 1
5 小红 19 1
2 李四 20 3
4 赵六 24 4
3 王五 30 5

相同的 age 排名一样,也就是说这里没有第二名。

不过需要注意的是,不能自定义相同 age 的顺序,否则它的排名会变化

age 相同,按照 id 降序排列

select *, rank() over(order by age, id desc) as 排名 from sequence;

如图所示:

id name age 排名
5 小红 19 1
1 张三 19 2
2 李四 20 3
4 赵六 24 4
3 王五 30 5

会根据 ageid 两个维度进行排序,也就不存在两个并列第一名了。

dense_rank() 排序相同时,会重复,但不会跳过重复的排名

age 进行升序排列,需要结合 over() 来使用

select *, dense_rank() over(order by age) as 排名 from sequence;

如图所示:

id name age 排名
1 张三 19 1
5 小红 19 1
2 李四 20 2
4 赵六 24 3
3 王五 30 4

age 相同的进行排序,并列第一名,但是后面的数据并不会跳过第二名,而是紧接着第一名排序

它和 rank 一样,不能自定义相同 age 的顺序,否则它的排名也会变化,因为排序会按照两个维度来。