2

我有一个表格,其中包含每个球员参加过的每场比赛的记录。从这个问题的最佳答案开始,我已经有了一个很好的开端:Ranking with Millions entries,并且目前正在使用这个查询来检索每个玩家的最高分和他们的排名:

SET @rank=0;

SELECT user_id, score, rank FROM (
    SELECT *, @rank := @rank + 1 as rank
    FROM high_scores
    JOIN (
        SELECT user_id as user_id2, MAX(score) AS max_score         
        FROM high_scores
        GROUP BY user_id2
        ORDER BY max_score DESC) AS max_score_table                
    ON max_score = high_scores.score AND high_scores.user_id = user_id2) derived_table
ORDER BY rank;

同样,这给了我一个很好的有序列表,列出了每个玩家的最高分和排名;但是,我还希望能够提供一个特定user_id的结果并将结果过滤到该用户的分数以及 X 数量的周围更高和更低的分数。

我认为我需要SELECT ... WHERE对“derived_table”执行一个user id并使用返回的行'rank'来过滤顶级SELECT语句,但除了查询甚至不被接受('derived_table 不存在'),我这样做的方式需要我重新查询derived_table 两次(用于大于和小于测试),从而使查询效率甚至低于应有的效率。

如何过滤高分的完整列表并将排名下降到单个user_id条目和 X 数量的周围条目?对我试图提出的代码(或我目前拥有的代码)的任何见解将不胜感激。

4

1 回答 1

0
SELECT ranks.rank, ranks.user_id, ranks.maxscore FROM (

  -- find the rank of each user by counting the number of
  -- users who have a score greater than that user's highest
  SELECT   currentuser.user_id,
           currentuser.maxscore,
           IFNULL(COUNT(DISTINCT high_scores.user_id),0) rank
  FROM     high_scores JOIN (
    -- current user's highest score
    SELECT user_id, MAX(score) maxscore FROM high_scores GROUP BY user_id
  ) currentuser ON high_scores.score > currentuser.maxscore
  GROUP BY currentuser.user_id

) ranks JOIN (

  -- find the rank of the user we want similarly
  SELECT IFNULL(COUNT(DISTINCT user_id),0) rank
  FROM   high_scores JOIN (
    -- our user's highest score
    SELECT MAX(score) maxscore FROM high_scores WHERE user_id = ?
  ) userscore ON high_scores.score > userscore.maxscore

-- filter for only those who are within given range from our user's rank
) userrank ON ranks.rank BETWEEN userrank.rank - ? AND userrank.rank + ?

-- sort the results
ORDER BY ranks.rank
于 2012-10-21T10:43:27.433 回答