Open techiall opened 6 years ago
编写一个 SQL 查询来实现分数排名。如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。
+----+-------+ | Id | Score | +----+-------+ | 1 | 3.50 | | 2 | 3.65 | | 3 | 4.00 | | 4 | 3.85 | | 5 | 4.00 | | 6 | 3.65 | +----+-------+
例如,根据上述给定的 Scores 表,你的查询应该返回(按分数从高到低排列):
Scores
+-------+------+ | Score | Rank | +-------+------+ | 4.00 | 1 | | 4.00 | 1 | | 3.85 | 2 | | 3.65 | 3 | | 3.65 | 3 | | 3.50 | 4 | +-------+------+
原先的想法使用 SQL 里面的变量来做的,然后点执行代码的时候发现过不去,就放弃了这种想法。
使用 count 计数, distinct 去重,比较两个分数,在利用 order by 进行排序即可。
mysql
select s.Score, (select count(distinct s1.Score) from Scores s1 where s1.Score >= s.Score) Rank from Scores s order by s.Score desc;
测试成功后,发现用的时间有点长……
我看了一下其他人的提交,找了执行用时较少的代码看,居然发现他们是使用变量,而且思路更简单。
(其实执行代码那里使用变量测试不通过,但是直接提交一发,就知道是不是正确了。
思路如下
预选设置一个分数,实际生活中是不存在负的分数的,因此选一个负数的值作为预置的分数即可。
rank 的起始为 0,递增即可。
rank 递增的条件:等于上一次的 rank,加上判断分数是否等于上一次的分数。
比较的两个值不相等就是 1,就递增,如果相等,就不递增。
@cur_rank := @cur_rank + (@pre_score != (@pre_score := s.Score)) 相当于 @tmp1 = (@pre_score := s.Score); @tmp2 = @pre_score != tmp; // 值只会是 0 或者 1 @cur_rank = @cur_rank + tmp2;
set @pre_score = -324234; set @cur_rank = 0; select s.Score, (@cur_rank := @cur_rank + (@pre_score != (@pre_score := s.Score))) Rank from Scores s order by 1 desc;
编写一个 SQL 查询来实现分数排名。如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。
例如,根据上述给定的
Scores
表,你的查询应该返回(按分数从高到低排列):原先的想法使用 SQL 里面的变量来做的,然后点执行代码的时候发现过不去,就放弃了这种想法。
使用 count 计数, distinct 去重,比较两个分数,在利用 order by 进行排序即可。
mysql
测试成功后,发现用的时间有点长……
我看了一下其他人的提交,找了执行用时较少的代码看,居然发现他们是使用变量,而且思路更简单。
(其实执行代码那里使用变量测试不通过,但是直接提交一发,就知道是不是正确了。
思路如下
预选设置一个分数,实际生活中是不存在负的分数的,因此选一个负数的值作为预置的分数即可。
rank 的起始为 0,递增即可。
rank 递增的条件:等于上一次的 rank,加上判断分数是否等于上一次的分数。
比较的两个值不相等就是 1,就递增,如果相等,就不递增。