Mysql常用函数之Rank排名函数详解
作者:pan_mlpan
这篇文章主要介绍了Mysql常用函数之Rank排名函数详解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
mysql中的排名函数
主要介绍一下mysql里面的排名函数,涉及到的函数有以下几个:
rank()、dense_rank()、row_number()
1、准备工作
建立一个rank表:
create table rank( id int(10) not null primary key, name varchar(20) not null, score int(10) not null );
插入一些数据:
insert into rank values(1,'a',100); insert into rank values(2,'b',100); insert into rank values(3,'c',95); insert into rank values(4,'d',95); insert into rank values(5,'e',95); insert into rank values(6,'a',90); insert into rank values(7,'a',89);
表及数据的截图:
2、rank() 函数
语法结构:
RANK() OVER ( PARTITION BY <expression>[{,<expression>...}] ORDER BY <expression> [ASC|DESC], [{,<expression>...}] )
按照某字段的排序结果添加排名,但它是跳跃的、间断的排名
(1)若按照分数直接进行排序的话,例如按照score进行排名
两个并列第一名后,下一个是第三名。
SELECT score, rank() over(ORDER BY score desc) as 'Rank' FROM rank;
结果:
+------+---------+ | score| Rank | +------+---------+ | 100 | 1 | | 100 | 1 | | 95 | 3 | | 95 | 3 | | 95 | 3 | | 90 | 6 | | 89 | 7 | +------+---------+ 7 rows in set (0.02 sec)
(2)若按照某个字段分区进行排序的话,例如按照name进行分区,根据分数进行排名:
SELECT name , score , rank() over(partition by name ORDER BY score desc) as 'Rank' FROM rank;
首先,PARTITION BY子句按姓名将结果集分成多个分区。
然后,ORDER BY子句按分数对结果集进行排序。
结果:
+------+------+---------+ | name | score| Rank | +------+------+---------+ | a | 100 | 1 | | a | 90 | 2 | | a | 89 | 3 | | b | 100 | 1 | | c | 95 | 1 | | d | 95 | 1 | | e | 95 | 1 | +------+------+---------+ 7 rows in set (0.02 sec)
3、row_number() 函数
MySQL ROW_NUMBER()从8.0版开始引入了功能。这ROW_NUMBER()是一个窗口函数或分析函数,它为从1开始应用的每一行分配一个序号
语法结构如下:
ROW_NUMBER() OVER ( PARTITION BY <expression>[{,<expression>...}] ORDER BY <expression> [ASC|DESC], [{,<expression>...}]
例如还是根据分数进行排序
SELECT row_number() OVER ( ORDER BY score ) row_num, score FROM rank;
结果:
+-------+------+---------+ |row_num| score| Rank | +------ +------+---------+ | 1 | 100 | 1 | | 2 | 100 | 2 | | 3 | 95 | 3 | | 4 | 95 | 1 | | 5 | 95 | 1 | | 6 | 90 | 1 | | 7 | 89 | 1 | +-------+------+---------+ 7 rows in set (0.02 sec)
其次,使用ROW_NUMBER()函数将行划分为所有列的分区。对于每个唯一的行集,将重新开始行号。
SELECT id, name, ROW_NUMBER() OVER (PARTITION BY name ORDER BY name) AS row_num FROM rank;
结果:
+------+------+---------+ | id | name | row_num | +------+------+---------+ | 1 | a | 1 | | 2 | a | 2 | | 3 | a | 3 | | 4 | b | 1 | | 5 | c | 1 | | 6 | d | 1 | | 7 | e | 1 | +------+------+---------+ 7 rows in set (0.02 sec)
4、dense_rank() 函数
dense 英语中指“稠密的、密集的”。dense_rank()是的排序数字是连续的、不间断。当有相同的分数时,它们的排名结果是并列的,例如,1,2,2,3。
语法结构:
DENSE_RANK() OVER ( PARTITION BY <expression>[{,<expression>...}] ORDER BY <expression> [ASC|DESC], [{,<expression>...}] )
例如,还是根据成绩进行排名:
SELECT score, dense_rank() over(ORDER BY score desc) as 'Rank' FROM rank;
结果:
+------+---------+ | score| Rank | +------+---------+ | 100 | 1 | | 100 | 1 | | 95 | 2 | | 95 | 2 | | 95 | 2 | | 90 | 3 | | 89 | 4 | +------+---------+ 7 rows in set (0.02 sec)
若按照某个字段分区进行排序的话,例如按照name进行分区,根据分数进行排名
SELECT name , score , dense_rank() over(partition by name ORDER BY score desc) as 'Rank' FROM rank;
首先,PARTITION BY子句按姓名将结果集分成多个分区。
然后,ORDER BY子句按分数对结果集进行排名。
结果:
+------+------+---------+ | name | score| Rank | +------+------+---------+ | a | 100 | 1 | | a | 90 | 2 | | a | 89 | 3 | | b | 100 | 1 | | c | 95 | 1 | | d | 95 | 1 | | e | 95 | 1 | +------+------+---------+ 7 rows in set (0.02 sec)
这数据可能不太明显,如果再插入一条数据:
insert into rank values(8,'a',90);
然后查询,结果如下,与rank函数执行的结果就可以看到区别了:
+------+------+---------+ | name | score| Rank | +------+------+---------+ | a | 100 | 1 | | a | 90 | 2 | | a | 90 | 2 | | a | 89 | 3 | | b | 100 | 1 | | c | 95 | 1 | | d | 95 | 1 | | e | 95 | 1 | +------+------+---------+ 7 rows in set (0.02 sec)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。