在数据管理领域,排序和排名是两个常见的需求,无论是企业内部的绩效考核,还是体育比赛中的成绩名次,都需要对数据进行排序和排名,MySQL作为流行的关系型数据库管理系统,提供了多种实现数据排名的方法,本文将深入探讨MySQL中的排名功能,包括使用变量和窗口函数两种主要方式。
排名通常指根据某一列的数据(如成绩、销售额等)对记录进行排序,并赋予每条记录一个名次,MySQL中实现排名的方式主要有两种:通过用户定义变量和使用窗口函数。
1. 普通排名
普通排名是指为每一行数据分配一个唯一的排名,无论数据是否相同,以下是一个示例:
CREATE TABLE scores_tb ( id INT AUTO_INCREMENT PRIMARY KEY, xuehao INT NOT NULL, score INT NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO scores_tb (xuehao, score) VALUES (1001, 89), (1002, 99), (1003, 96), (1004, 96), (1005, 92), (1006, 90), (1007, 90), (1008, 94); SELECT xuehao, score, @curRank := @curRank + 1 AS rank FROM scores_tb, (SELECT @curRank := 0) r ORDER BY score DESC;
结果如下:
xuehao | score | rank |
1002 | 99 | 1 |
1003 | 96 | 2 |
1004 | 96 | 3 |
1008 | 94 | 4 |
1005 | 92 | 5 |
1006 | 90 | 6 |
1007 | 90 | 7 |
1001 | 89 | 8 |
这种排名方式没有间隔,即使分数相同也会得到不同的排名。
2. 并列排名
有时候需要处理并列排名的情况,即相同分数的记录应具有相同的排名,并且下一记录的排名应跳过相应的人数,如果两名学生都得了最高分,则他们应并列第一,而随后的学生排名应从第三开始。
SELECT xuehao, score, CASE WHEN @prevRank = score THEN @curRank WHEN @prevRank := score THEN @curRank := @curRank + 1 END AS rank FROM scores_tb, (SELECT @curRank := 0, @prevRank := NULL) r ORDER BY score DESC;
结果如下:
xuehao | score | rank |
1002 | 99 | 1 |
1003 | 96 | 2 |
1004 | 96 | 2 |
1008 | 94 | 4 |
1005 | 92 | 5 |
1006 | 90 | 6 |
1007 | 90 | 6 |
1001 | 89 | 8 |
这种情况下,相同分数的记录得到了相同的排名,且下一个排名有间隔。
3. 并列排名无间隔
有时需要并列排名且无间隔,即相同分数的记录应有相同的排名,但下一个排名不跳过,如果两名学生并列第一,下一个学生应为第二名。
SELECT xuehao, score, CASE WHEN @prevRank = score THEN @curRank WHEN @prevRank := score THEN @curRank := @curRank + 1 END AS rank FROM scores_tb, (SELECT @curRank := 0, @prevRank := NULL) r ORDER BY score DESC;
结果如下:
xuehao | score | rank |
1002 | 99 | 1 |
1003 | 96 | 2 |
1004 | 96 | 2 |
1008 | 94 | 3 |
1005 | 92 | 4 |
1006 | 90 | 5 |
1007 | 90 | 5 |
1001 | 89 | 6 |
这种情况下,相同分数的记录得到了相同的排名,且下一个排名无间隔。
从MySQL8.0版本开始,MySQL引入了窗口函数,极大地简化了排名操作,常用的窗口函数包括ROW_NUMBER()
,RANK()
, 和DENSE_RANK()
。
-- 创建测试表并插入数据 CREATE TABLE scores_tb ( id INT AUTO_INCREMENT PRIMARY KEY, xuehao INT NOT NULL, score INT NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO scores_tb (xuehao, score) VALUES (1001, 89), (1002, 99), (1003, 96), (1004, 96), (1005, 92), (1006, 90), (1007, 90), (1008, 94);
1.ROW_NUMBER()
函数
ROW_NUMBER()
函数为结果集中的每一行分配唯一的行号,不考虑是否有并列。
SELECT xuehao, score, ROW_NUMBER() OVER (ORDER BY score DESC) AS row_r FROM scores_tb;
结果如下:
xuehao | score | row_r |
1002 | 99 | 1 |
1003 | 96 | 2 |
1004 | 96 | 3 |
1008 | 94 | 4 |
1005 | 92 | 5 |
1006 | 90 | 6 |
1007 | 90 | 7 |
1001 | 89 | 8 |
2.RANK()
函数
RANK()
函数为结果集中的每一行分配排名,相同值的排名相同,不同值的排名会跳跃。
SELECT xuehao, score, RANK() OVER (ORDER BY score DESC) AS rank FROM scores_tb;
结果如下:
xuehao | score | rank |
1002 | 99 | 1 |
1003 | 96 | 2 |
1004 | 96 | 2 |
1008 | 94 | 4 |
1005 | 92 | 5 |
1006 | 90 | 6 |
1007 | 90 | 6 |
1001 | 89 | 8 |
DENSE_RANK()
函数
DENSE_RANK()
函数类似于RANK()
,但对于相同值的排名不会跳跃。
SELECT xuehao, score, DENSE_RANK() OVER (ORDER BY score DESC) AS dense_r FROM scores_tb;
随着互联网的普及和信息技术的飞速发展台湾vps云服务器邮件,电子邮件已经成为企业和个人日常沟通的重要工具。然而,传统的邮件服务在安全性、稳定性和可扩展性方面存在一定的局限性。为台湾vps云服务器邮件了满足用户对高效、安全、稳定的邮件服务的需求,台湾VPS云服务器邮件服务应运而生。本文将对台湾VPS云服务器邮件服务进行详细介绍,分析其优势和应用案例,并为用户提供如何选择合适的台湾VPS云服务器邮件服务的参考建议。
工作时间:8:00-18:00
电子邮件
1968656499@qq.com
扫码二维码
获取最新动态