前言
最近业务上碰到这样一个需求,需要对表按照某一个字段进行排序,并且将得到的排名写入对应的排名字段。这个需求于我而言确实没有遇到过,好在试着摸索一番得以解决,故写博客记录一下。
一、数据库表结构和样例数据
本文中我们创建一张简单的成绩表来进行测试,表的结构和数据也很简单,这里不再赘述,直接放代码:
CREATE TABLE `grades` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`grade` int(11) DEFAULT NULL,
`rankNum` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4;
INSERT into grades (grade) VALUE (87);
INSERT into grades (grade) VALUE (100);
INSERT into grades (grade) VALUE (95);
INSERT into grades (grade) VALUE (87);
INSERT into grades (grade) VALUE (45);
INSERT into grades (grade) VALUE (67);
INSERT into grades (grade) VALUE (75);
INSERT into grades (grade) VALUE (87);
创建表之后我们插入8条数据进行测试,当然,我们的排名字段暂时是为空的,最终效果如图:
二、排名操作
1.普通排名
普通排名就是指所有数据按其规则进行排序,尽管出现数据相同的情况,也依然存在先后顺序。
UPDATE
grades g1 INNER JOIN (SELECT id, grade,
@rank := @rank + 1 AS ranking
FROM
(SELECT @rank := 0) r,
grades
ORDER BY
grade DESC) g2
ON g1.id = g2.id SET g1.rankNum = g2.ranking;
运行结果如图,我们也能看出排名确实是按照降序排列,而且分数相同的排名依然是有序的:
2.无间隔排名
无间隔排名就是指当存在相同数据时,我们希望它们的排名是一样的,就比如2,2,3这组数据,最终的排名效果是1,1,2;其中3这个数据的排名并没有因为前面占有两个数据而变成3,这我们称无间隔。
UPDATE
grades g1 INNER JOIN (SELECT id, grade,
(CASE
WHEN @prevRank = grade THEN @currank
WHEN @prevRank := grade THEN @currank := @currank + 1
END) AS ranking
FROM
(SELECT @prevRank := NULL, @currank := 0) r,
grades
ORDER BY
grade DESC) g2
ON g1.id = g2.id SET g1.rankNum = g2.ranking;
运行结果如图,我们可以看出分数相同的87排名都是一样的,而在87之后的75的排名依然是4没有跳跃:
3.有间隔排名
这个排名规则是我业务上真正需要的,所谓的有间隔就是比如之前的例子2,2,3,那么最后的排名结果是1,1,3;这里的数据3不再是2了,会因为占有问题而跳跃。
UPDATE
grades g1 INNER JOIN (SELECT id, grade,
@currank := IF(@prevRank = grade, @currank, @rowrank) AS ranking,
@rowrank := @rowrank + 1,
@prevRank := grade
FROM
(SELECT @prevRank := NULL, @currank := 0, @rowrank := 1) r,
grades
ORDER BY
grade DESC) g2
ON g1.id = g2.id SET g1.rankNum = g2.ranking;
运行结果如图,我们可以看出此时的75已然变成了6,实现了跳跃:
总结
希望这篇博客对大家有所帮助!!!