天天看點

MySQL之LeetCode-178(分數排名)題目(中等)解題語句

題目(中等)

編寫一個 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 |

±------±-----+

解題語句

1.耗時530 ms

SELECT
    a.Score,
    SUM(
      CASE
        WHEN b.Score >= a.Score
        THEN 1
      END
    ) AS Rank
  FROM
    Scores a,
    (SELECT DISTINCT
      Score
    FROM
      Scores) b
  GROUP BY a.id
  ORDER BY a.Score DESC;

           

2.耗時944 ms

SELECT
  a.score AS Score,
  COUNT(DISTINCT b.score) AS Rank
FROM
  scores a,
  scores b
WHERE b.score >= a.score
GROUP BY a.id
ORDER BY a.score DESC
           

3.耗時1478 ms

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

這題可以将結果的兩個字段拆分,前面一個分數字段,就是簡單的查詢出來就可以了,重點在于後面的分數排名字段,需要自關聯找到分數有幾個檔位。

這裡需要注意的是前兩種解法由于使用了sum和count函數是以後面要使用group進行分組。

這裡的執行時間隻是一種參考方式,LeetCode中的時間多執行幾次每次都是不同的,而且差别還比較大。

但是第三種解題方法确實不推薦,這種方式在資料量大的時候每條結果都有一個子查詢,性能肯定不會好。