I am trying to solve this rank scores problem in leetcode: https://leetcode.com/problems/rank-scores/ and I have two solutions (mysql). Both work.
select a.Score as Score,
(select count(distinct b.Score) from Scores as b where b.Score>=a.score) as Rank
from Scores as a
order by a.Score desc;
and
select s1.Score,count(distinct(s2.score)) Rank
from
Scores s1,Scores s2
where
s1.score<=s2.score
group by s1.Id
order by Rank
But I am not sure why I have to use GROUP BY in solution two to make sure that sql calculate the count for each score (or else it returns the minimum score only), but I do not have to use it in solution one.
But I am not sure why I have to use GROUP BY in solution two to make sure that sql calculate the count for each score
The second query works by self-joining the table on an inequality condition: for each row in alias s1
, you get all rows in s2
that have a smaller or equal score. You then need to aggregate so you can count how many s2
rows there are for each s1
, which gives you the rank.
Note: if you are running MySQL 8.0, you can do this without a join or subquery, using window function rank()
, that does exactly what you want:
select score, rank() over(order by score desc) rn from scores
Finally: as of 2020, you should be using explicit, standard joins rather than old-school, implicit joins:
select s1.score, count(distinct(s2.score)) rn
from scores s1
inner join scores s2 on s1.score <= s2.score
group by s1.id, s1.score
order by rn