MySQL-选择排名前5名

问题描述

我正在尝试让用户排名,使其在每个节拍图中的表现都最高。

我在每个节拍图中都获得了用户最高的性能(仅将前5个演奏都加在一起),但是当重复一次节拍图中的最高性能时,它会失败...因为它计数两次

我基于这个solution,但是它对我来说效果不佳...

使用MysqL 5.7

我做错了什么?

Fiddle

使用此代码

SET group_concat_max_len := 1000000;

SELECT @i:=@i+1 rank,x.userID,x.totalperformance FROM (SELECT r.userID,SUM(r.performance) as totalperformance 
FROM 
(SELECT Rankings.*
FROM   Rankings INNER JOIN (
  SELECT   userID,GROUP_CONCAT(performance ORDER BY performance DESC) grouped_performance
  FROM     Rankings
  GROUP BY userID) group_max
  ON Rankings.userID = group_max.userID
     AND FIND_IN_SET(performance,grouped_performance) <= 5

ORDER BY
  Rankings.userID,Rankings.performance DESC) as r
  GROUP BY userID) x
  JOIN 
     (SELECT @i:=0) vars
 ORDER BY x.totalperformance DESC

预期结果:

+------+--------+------------------+
| rank | userID | totalperformance |
+------+--------+------------------+
| 1    | 1      | 450              |
+------+--------+------------------+
| 2    | 2      | 250              |
+------+--------+------------------+
| 3    | 5      | 140              |
+------+--------+------------------+
| 4    | 3      | 50               |
+------+--------+------------------+
| 5    | 75     | 10               | 
+------+--------+------------------+
| 6    | 45     | 0                | --
+------+--------+------------------+
| 7    | 70     | 0                | ----> This order is not relevant
+------+--------+------------------+
| 8    | 76     | 0                | --
+------+--------+------------------+

实际结果:

+------+--------+------------------+
| rank | userID | totalperformance |
+------+--------+------------------+
| 1    | 1      | 520              |
+------+--------+------------------+
| 2    | 2      | 350              |
+------+--------+------------------+
| 3    | 5      | 220              |
+------+--------+------------------+
| 4    | 3      | 100              |
+------+--------+------------------+
| 5    | 75     | 10               |
+------+--------+------------------+
| 6    | 45     | 0                | --
+------+--------+------------------+
| 7    | 70     | 0                | ----> This order is not relevant
+------+--------+------------------+
| 8    | 76     | 0                | --
+------+--------+------------------+

解决方法

正如您提到的那样,您在beatmaps中仅从每位用户中挑选出前5名性能,那么您可以尝试以下方式:

select @i:=@i+1,userid,performance from (
select userid,sum(performance) as performance from (
select 
  @row_number := CASE WHEN @last_category <> t1.userID THEN 1 ELSE @row_number + 1 END AS row_number,@last_category :=t1.userid,t1.userid,t1.beatmapid,t1.performance

from (
select 
 userid,beatmapid,max(performance) as performance
from Rankings 
group by userid,beatmapid
) t1 
CROSS JOIN (SELECT @row_number := 0,@last_category := null) t2
ORDER BY t1.userID,t1.performance desc
) t3
where row_number<=5
group by userid
)
t4 join  (SELECT @i := 0 ) t5
order by performance desc

以上查询不会考虑重复的性能得分,只会选择前5个性能值。

DEMO