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的運行效率得到了較大的提高.
PS:
如果您覺得我的文章對您有幫助,請關注我的微信公眾號,謝謝!
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/122820.html
標籤:MySQL

