MySQL通过联系对列进行排名

时间:2019-01-22 22:38:23

标签: mysql sql

给出具有以下架构的得分表

+----+-------+
| Id | Score |
+----+-------+
| 1  | 3.50  |
| 2  | 3.65  |
| 3  | 4.00  |
| 4  | 3.85  |
| 5  | 4.00  |
| 6  | 3.65  |
+----+-------+

我尝试了以下操作:

SET @prev_value = NULL;
SET @rank_count = 0;
SELECT Id, Score, CASE
    WHEN @prev_value = Score THEN @rank_count
    WHEN @prev_value := Score THEN @rank_count := @rank_count + 1
END AS Rank
FROM Scores
ORDER BY Score

为了获得

+-------+------+
| Score | Rank |
+-------+------+
| 4.00  | 1    |
| 4.00  | 1    |
| 3.85  | 2    |
| 3.65  | 3    |
| 3.65  | 3    |
| 3.50  | 4    |
+-------+------+

但是我得到了这个错误:

Line 3: SyntaxError: near 'SET @rank_count = 0;
SELECT Id, Score, CASE
    WHEN @prev_value := Score THEN @'

我做错了什么?

3 个答案:

答案 0 :(得分:0)

在MySQL 8.x中,您可以使用DENSE_RANK()函数,如下所示:

select 
  Score,
  dense_rank() over(order by Score desc) as Rank
from Scores
order by Score desc

答案 1 :(得分:0)

您可以计算所有大于每行分数的独特分数,并将结果加1:

select 
  s.score,
  ((select count(distinct score) from scores where score > s.score) + 1) rank
from scores s
order by s.score desc

请参见demo

答案 2 :(得分:0)

您可以使用变量。我认为您只需要一个查询:

SELECT Id, Score,
       (CASE WHEN @prev_value = Score THEN @rank_count
             WHEN @prev_value := Score THEN @rank_count := @rank_count + 1
        END) AS Rank
FROM (SELECT s.*
      FROM Scores s
      ORDER BY Score s
     ) s CROSS JOIN
     (SELECT @prev_value := NULL, @rank_count := 0) params;

最新的MySQL版本要求在子查询中进行排序。当然,最新版本提供DENSE_RANK()更好。