題目(中等)
編寫一個 SQL 查詢來實作分數排名。如果兩個分數相同,則兩個分數排名(Rank)相同。請注意,平分後的下一個名次應該是下一個連續的整數值。換句話說,名次之間不應該有“間隔”。
±—±------+
| Id | Score |
±—±------+
| 1 | 3.50 |
| 2 | 3.65 |
| 3 | 4.00 |
| 4 | 3.85 |
| 5 | 4.00 |
| 6 | 3.65 |
±—±------+
例如,根據上述給定的 Scores 表,你的查詢應該傳回(按分數從高到低排列):
±------±-----+
| Score | Rank |
±------±-----+
| 4.00 | 1 |
| 4.00 | 1 |
| 3.85 | 2 |
| 3.65 | 3 |
| 3.65 | 3 |
| 3.50 | 4 |
±------±-----+
解題語句
1.耗時530 ms
SELECT
a.Score,
SUM(
CASE
WHEN b.Score >= a.Score
THEN 1
END
) AS Rank
FROM
Scores a,
(SELECT DISTINCT
Score
FROM
Scores) b
GROUP BY a.id
ORDER BY a.Score DESC;
2.耗時944 ms
SELECT
a.score AS Score,
COUNT(DISTINCT b.score) AS Rank
FROM
scores a,
scores b
WHERE b.score >= a.score
GROUP BY a.id
ORDER BY a.score DESC
3.耗時1478 ms
SELECT
s.Score,
(SELECT
COUNT(DISTINCT Score)
FROM
Scores
WHERE Score >= s.Score) AS Rank
FROM
Scores AS s
ORDER BY s.Score DESC
這題可以将結果的兩個字段拆分,前面一個分數字段,就是簡單的查詢出來就可以了,重點在于後面的分數排名字段,需要自關聯找到分數有幾個檔位。
這裡需要注意的是前兩種解法由于使用了sum和count函數是以後面要使用group進行分組。
這裡的執行時間隻是一種參考方式,LeetCode中的時間多執行幾次每次都是不同的,而且差别還比較大。
但是第三種解題方法确實不推薦,這種方式在資料量大的時候每條結果都有一個子查詢,性能肯定不會好。