Rank Scores_leetcode#178

时间:2018-02-17 04:02:02

标签: mysql sql

有人可以帮忙解释如何解决这个问题吗?我是sql的初学者,不知道如何使用变量。

编写SQL查询以给出Scores表的排名分数。如果两个分数之间存在平局,则两者应具有相同的排名。请注意,在平局之后,下一个排名数应该是下一个连续的整数值。换句话说,应该没有"漏洞"在队伍之间。

Question Description

https://leetcode.com/problems/rank-scores/description/

我已经在讨论论坛中查看了解决方案,但仍然无法理解其背后的逻辑。如果有人能够提供一步一步的解释,将不胜感激。 其中一个可能的解决方案是(没有变量):

select scores.Score, count(ranking.Score) as Rank
from scores, (select distinct Score from scores) ranking
where ranking.score>=scores.Score
group by scores.Id
order by scores.Score desc

谢谢!

2 个答案:

答案 0 :(得分:4)

让我们先看一下预期输入和输出的例子:

INPUT
+----+-------+
| Id | Score |
+----+-------+
| 1  | 3.50  |
| 2  | 3.65  |
| 3  | 4.00  |
| 4  | 3.85  |
| 5  | 4.00  |
| 6  | 3.65  |
+----+-------+

OUTPUT
+-------+------+
| Score | Rank |
+-------+------+
| 4.00  | 1    |
| 4.00  | 1    |
| 3.85  | 2    |
| 3.65  | 3    |
| 3.65  | 3    |
| 3.50  | 4    |
+-------+------+

因此,任务是将所有相同的分数分组,然后从最大到最小排序。让我们一步一步看看你提到的解决方案是如何实现的。首先,它创建一个名为ranking的帮助表 - 注意(select distinct Score from scores) ranking。其内容将是:

+----+--+
| Score |
+----+--+
| 3.50  |
| 3.65  |
| 4.00  |
| 3.85  |        
+----+--+

注意所有重复分数是如何消除的(这是distinct关键字的目的)。接下来,表rankingscores之间存在联接(隐藏在where部分中),我们将scores表中的每条记录与来自ranking的所有记录连接起来得分大于或等于的表格。因此,这个中期阶段的结果将是:

+----+-------+---------+
| Id | Score | r.Score |
+----+-------+---------+
| 1  | 3.50  | 3.50    |
| 1  | 3.50  | 3.65    |
| 1  | 3.50  | 3.85    |
| 1  | 3.50  | 4.00    |
| 2  | 3.65  | 3.65    |
| 2  | 3.65  | 3.85    |
| 2  | 3.65  | 4.00    |
| 3  | 4.00  | 4.00    |
| 4  | 3.85  | 3.85    |
| 4  | 3.85  | 4.00    |
| 5  | 4.00  | 4.00    |
| 6  | 3.65  | 3.65    |
| 6  | 3.65  | 3.85    |
| 6  | 3.65  | 4.00    |
+----+-------+---------+

接下来是group by,它将具有相同Id的所有记录分组到一个记录中。由于在select部分我们有count(ranking.Score),因此分组的结果将是每个Id的不同排名分数的计数。由于我们仅从ranking加入了大于或等于原始分数的分数,因此此计数将提供所请求的排名。我们差不多完成了:

+----+-------+--------+-------+
| Id | count(r.Score) | Score |
+----+-------+--------+-------+
| 1  |       4        | 3.50  |
| 2  |       3        | 3.65  |
| 3  |       1        | 4.00  |
| 4  |       2        | 3.85  |
| 5  |       1        | 4.00  |
| 6  |       3        | 3.65  |
+----+-------+--------+-------+

现在最简单的部分 - order by按分数排序结果。由于select不包含Id,因此省略该列,我们得到最终结果。希望这有帮助!

P.S。因为我们使用MySQL,所以我们可以从scores.Score部分省略group by并仍在select中使用它 - 这在其他SQL引擎中是不允许的。你表示你是初学者,所以不要为此担心,只要提一下就完整了。

答案 1 :(得分:1)

select S.Score, Dense_Rank() over(order by S.Score desc) 'Rank' from Scores S