MySQL - Select 排名前 5 位
MySQL - Select Top 5 with Rankings
我正在尝试让用户在每个谱面中获得最高表现排名。
我在每个谱面中都获得了用户最高表现(只取前 5 名表现)并将它们加在一起,但是当重复一个谱面中的最高表现时它失败了...因为它计数两次
我住在这个 solution,但它不太适合我...
使用 MySQL 5.7
我做错了什么?
使用此代码:
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 个性能值。
我正在尝试让用户在每个谱面中获得最高表现排名。
我在每个谱面中都获得了用户最高表现(只取前 5 名表现)并将它们加在一起,但是当重复一个谱面中的最高表现时它失败了...因为它计数两次
我住在这个 solution,但它不太适合我...
使用 MySQL 5.7
我做错了什么?
使用此代码:
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 个性能值。