題目描述: 編寫一個 SQL 查詢來實現分數排名。如果兩個分數相同,則兩個分數排名(Rank)相同。請註意,平分後的下一個名次應該是下一個連續的整數值。換句話說,名次之間不應該有“間隔”。 例如,根據上述給定的 Scores 表,你的查詢應該返回(按分數從高到低排列): SQL架構: 解題思路: o ...
題目描述:
編寫一個 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 | +-------+------+
SQL架構:
Create table If Not Exists Scores (Id int, Score DECIMAL(3,2)); Truncate table Scores; insert into Scores (Id, Score) values ('1', '3.5'); insert into Scores (Id, Score) values ('2', '3.65'); insert into Scores (Id, Score) values ('3', '4.0'); insert into Scores (Id, Score) values ('4', '3.85'); insert into Scores (Id, Score) values ('5', '4.0'); insert into Scores (Id, Score) values ('6', '3.65');
解題思路:
oracle可以使用排名函數進行排名,因為名次之間不應該有“間隔”,所以要使用dense_rank()函數,這個函數排的名次是連續的,rank()函數會跳過(併列排名),mysql依然是使用自定義變數來進行排名。
解題方案:
oracle
select round(a.score,2) as score, b.rank from Scores a join (select a.*, rownum as rank from (select distinct a.score from Scores a order by a.score desc) a) b on a.score = b.score order by b.rank
mysql
SELECT ROUND(a.score, 2) AS score, b.rank FROM Scores a JOIN ( SELECT a.*, (@rowNum :=@rowNum + 1) AS rank FROM ( SELECT DISTINCT a.score FROM Scores a ) a, (SELECT(@rowNum := 0)) b ORDER BY a.score DESC ) b ON a.score = b.score ORDER BY b.rank