[LeetCode]Rank Scores

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    |
+-------+------+

 

This question lets us sort the scores. If the two scores are the same, there is the same ranking. It should be noted that if there is the same ranking, the next ranking number should be a continuous integer value:

Here, let's expand a bit and use Excel functions to solve this problem:

In Excel, you can use the SUMPRODUCT() function to solve:

 Then we use the SQL statement to achieve this requirement:

Solution one:

SELECT Score, (SELECT COUNT(DISTINCT Score) FROM Scores WHERE Score >= s.Score)  Rank FROM Scores s ORDER BY Score DESC;

 The solution to this problem is to sort the scores in reverse order, and then compare the scores of each subject after deduplication to count them;

Let's make another extension: the results are still ranked, but the requirement is that when the ranking is to be repeated, the subsequent rankings will skip the ranking of repeated rankings.

We know that it can be achieved using the Rank function in Excel:

So how to achieve this ranking in SQL: 

select score, RANK() OVER(order by Score DESC) rank from scores ORDER BY score DESC;

Here you can use the ranking function to achieve this requirement.

 

 Solution two:

SELECT Score,
(SELECT COUNT(*) FROM (SELECT DISTINCT Score s FROM Scores ) t WHERE s >= Score) Rank
FROM Scores ORDER BY Score DESC;

Solution 2 and Solution 1 have the same problem-solving ideas, but the writing method is slightly different.

 

Solution three:

SELECT s.Score, COUNT(DISTINCT t.Score) Rank 
FROM Scores s JOIN Scores t ON s.Score <= t.Score
GROUP BY s.Id ORDER BY s.Score DESC; 

This method uses inner join, join is a short form of inner join, self and self are intercrossed, the condition is that the score of the right table is greater than or equal to the left table, and then grouped together according to the descending order of scores.

 

Solution four:

SELECT Score,
@rank := @rank + (@pre <> (@pre := Score)) Ranking
FROM Scores, (SELECT @rank := 0, @pre := -1) INIT 
ORDER BY Score DESC;

Two variables are used here. When the variable is used, it needs to be prefixed with @. Here := means assignment. If there is a Set keyword in front of it, you can directly use the = sign to assign a value. If not, you must use := To assign a value, two variables rank and pre, where rank represents the current rank, pre represents the previous score, <> in the following code represents not equal, if the left and right sides are not equal, return true or 1, if they are equal, return false or 0. Initialize rank to 0, pre to -1, and then sort the scores in descending order. For score 4, pre is assigned 4, which is different from the previous pre value of -1, so rank needs to be added by 1, then the rank of score 4 is 1 , the next score is still 4, then the value of pre is the same as the previous 4, so the rank must be increased by 0, so the rank of this score 4 is also 1, and so on, the rank of all scores can be calculated.

 

Reprinted in: https://www.cnblogs.com/lsyb-python/p/11045200.html

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324033853&siteId=291194637