0%

MySQL实现Rank排名

  • Hmm..就是在leetcode上面做题碰到了一个题目,让用SQL实现根据分值排序,原题描述如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    编写一个 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 |
    +-------+------+
  • 生产中应该不会遇到这种问题吧。。有的话应该也是新出表之类的解决,不过想了想,这个题还真么啥解决思路(自己引用自己还是内外层的。。在这之前真不会TAT)

  • 结合别人的答案,总算是弄明白了这个SQL是怎么写了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT
Score,
(
SELECT
count( DISTINCT score )
FROM
Scores
WHERE
score >= s.score
) AS Rank
FROM
Scores s
ORDER BY
Score DESC;
  • 外层其实很好理解,查询score表中Score和Rank,倒序一下。

  • 内层就是把外层每条的Score拿到(语句中的s.score),然后统计一下不小于s.score的值(去重),这个结果也就是对应的RanK了。

  • 换个条件。。如果两个分数相同,则两个分数排名(Rank)相同,名次之间“间隔”,也可以用这个思路来解决。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT
Score,
(
SELECT
count( score ) + 1
FROM
Scores
WHERE
score > s.score
) AS Rank
FROM
Scores s
ORDER BY
Score DESC;