有人可以帮忙解释如何解决这个问题吗?我是sql的初学者,不知道如何使用变量。
编写SQL查询以给出Scores表的排名分数。如果两个分数之间存在平局,则两者应具有相同的排名。请注意,在平局之后,下一个排名数应该是下一个连续的整数值。换句话说,应该没有"漏洞"在队伍之间。
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
谢谢!
答案 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
关键字的目的)。接下来,表ranking
和scores
之间存在联接(隐藏在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