此題,其本質就是賦值行號(需要註意分數相同的情景). 在實踐過程中,初版答案如下所示: 此處,使用 來統計行號,註意使用 來區分相同分數. 但是,此解題方案的效率較差, 運行肯定是越快越好. 因此,在 中引入變數來賦值行號,以替代耗時的 操作. 此處,查詢是在 與臨時表之間進行 . 此外,使用臨時變 ...
Write a SQL query to rank scores. If there is a tie between two scores, both should have the same ranking. Note that after a tie, the next ranking number should be the next consecutive integer value. In other words, there should be no "holes" between ranks.
+----+-------+
| Id | Score |
+----+-------+
| 1 | 3.50 |
| 2 | 3.65 |
| 3 | 4.00 |
| 4 | 3.85 |
| 5 | 4.00 |
| 6 | 3.65 |
+----+-------+
For example, given the above Scores table, your query should generate the following report (order by highest score):
+-------+------+
| Score | Rank |
+-------+------+
| 4.00 | 1 |
| 4.00 | 1 |
| 3.85 | 2 |
| 3.65 | 3 |
| 3.65 | 3 |
| 3.50 | 4 |
+-------+------+
此題,其本質就是賦值行號(需要註意分數相同的情景).
在實踐過程中,初版答案如下所示:
# Write your MySQL query statement below
SELECT
a.Score AS Score,
(SELECT COUNT(DISTINCT b.Score) FROM Scores b where b.Score >= a.Score) AS Rank
FROM Scores a ORDER BY a.Score DESC;
此處,使用select count
來統計行號,註意使用distinct
來區分相同分數.
但是,此解題方案的效率較差,sql
運行肯定是越快越好.
因此,在sql
中引入變數來賦值行號,以替代耗時的select count
操作.
# Write your MySQL query statement below
SELECT
Score,
@row := @row + (@pre <> (@pre := Score)) AS Rank
FROM Scores, (SELECT @row := 0, @pre := -1) t
ORDER BY Score DESC;
此處,查詢是在Scores
與臨時表之間進行cross join
.
此外,使用臨時變數(@row,@pre)記錄行號.
Tips
:
- 通過
@pre
與當前Score
的比較,確定是否+1,需要註意mysql
中的true/false
為0/1
); - 在
sql
中,set/update
語句中,=
表示賦值;在set/update/select
中,:=
表示賦值,因此使用:=
.
通過以上改進,mysql
的運行效率得到了較大的提高.