我只需要总结11个事件中每个球员的5个最佳成绩。下面的查询创建了一个排行榜,将所有分数相加,但我只能将5个最佳分数相加。
我已将查询缩写为仅显示4个事件,并获得3个最佳结果以缩短帖子,但希望它能解决我需要的内容。
SELECT playerID AS Player,
SUM(CASE WHEN championshipleaderboard.eventID = 1 THEN championshipleaderboard.points ELSE 0 END) AS Event1,
SUM(CASE WHEN championshipleaderboard.eventID = 2 THEN championshipleaderboard.points ELSE 0 END) AS Event2,
SUM(CASE WHEN championshipleaderboard.eventID = 3 THEN championshipleaderboard.points ELSE 0 END) AS Event3,
SUM(CASE WHEN championshipleaderboard.eventID = 4 THEN championshipleaderboard.points ELSE 0 END) AS Event4,
SUM(championshipleaderboard.points) AS Total
FROM (
championshipleaderboard JOIN members ON championshipleaderboard.playerId = members.playerId
)
GROUP BY championshipleaderboard.playerId
ORDER BY Total DESC;
表格:Championshipleaderboard
+--------+---------+--------+
| Player | EventID | Points |
+--------+---------+--------+
| 1 | 1 | 25 |
| 2 | 1 | 20 |
| 1 | 2 | 15 |
| 2 | 2 | 13 |
| 1 | 3 | 20 |
| 2 | 3 | 12 |
| 1 | 4 | 20 |
| 2 | 4 | 10 |
+--------+---------+--------+
当前结果是
+--------+--------+--------+--------+--------+-------+
| Player | Event1 | Event2 | Event3 | Event4 | Total |
+--------+--------+--------+--------+--------+-------+
| 1 | 25 | 15 | 20 | 20 | 80 |
| 2 | 20 | 13 | 12 | 10 | 55 |
+--------+--------+--------+--------+--------+-------+
所需结果为
+--------+--------+--------+--------+--------+--------------+
| Player | Event1 | Event2 | Event3 | Event4 | Total(best3) |
+--------+--------+--------+--------+--------+--------------+
| 1 | 25 | 15 | 20 | 20 | 65 |
| 2 | 20 | 13 | 12 | 10 | 45 |
+--------+--------+--------+--------+--------+--------------+
答案 0 :(得分:2)
您可以使用相关的子查询来找到最佳成绩第三名,并将总和等于或大于最佳成绩第三名:
SELECT Player
, MIN(CASE WHEN Eventid = 1 THEN points END) AS Event1
, MIN(CASE WHEN Eventid = 2 THEN points END) AS Event2
, MIN(CASE WHEN Eventid = 3 THEN points END) AS Event3
, MIN(CASE WHEN Eventid = 4 THEN points END) AS Event4
, SUM(CASE WHEN (Points, ID) >= (
SELECT Points, ID
FROM t AS x
WHERE x.Player = t.Player
ORDER BY Points DESC, ID DESC
LIMIT 2, 1
) THEN Points END) AS TopThree
FROM t
GROUP BY Player
请注意,按Points DESC, ID DESC
排序会破坏排序点之间的联系;因此,如果玩家的分数是(1, 20), (2, 20), (3, 30), (4, 30)
,则(4, 30), (3, 30), (2, 20)
会被求和。
答案 1 :(得分:2)
这是一种方法-尽管在MySQL 8+中,您将使用更多现代技术...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(Player INT NOT NULL
,EventID INT NOT NULL
,Points INT NOT NULL
,PRIMARY KEY(player,eventid)
);
INSERT INTO my_table VALUES
(1,1,25),
(2,1,20),
(1,2,15),
(2,2,13),
(1,3,20),
(2,3,12),
(1,4,20),
(2,4,10);
SELECT player
, SUM(points) top3
FROM
( SELECT x.*
, CASE WHEN @prev = player THEN @i:=@i+1 ELSE @i:=1 END i
, @prev:=player
FROM my_table x
, (SELECT @prev:=null,@i:=0) vars ORDER BY player,points
DESC) a
WHERE i<=3
GROUP
BY player;
+--------+------+
| player | top3 |
+--------+------+
| 1 | 65 |
| 2 | 45 |
+--------+------+
答案 2 :(得分:1)
另一种方法:https://www.db-fiddle.com/f/332F6XA3J3GaxXeD7LFP81/0
实时测试:
with ranking as
(
select
player,
rank() over(partition by player order by points desc) as xrank,
points
from tbl
)
select
player,
sum(if(eventid = 1, points, 0)) as event1,
sum(if(eventid = 2, points, 0)) as event2,
sum(if(eventid = 3, points, 0)) as event3,
sum(if(eventid = 4, points, 0)) as event4,
sum(
if(
(player,points) in
(select player,points
from ranking
where xrank <= 3),
points,
0
)
) as best3
from tbl
group by player
输出:
| player | event1 | event2 | event3 | event4 | best3 |
| ------ | ------ | ------ | ------ | ------ | ----- |
| 1 | 25 | 15 | 20 | 20 | 65 |
| 2 | 20 | 13 | 12 | 10 | 45 |
答案 3 :(得分:0)
我建议在由concat(玩家ID,事件ID)分组的查询中使用子查询,且子查询的限制为3(或5,或者很多)。
在我自己的数据库中的类似表上对此进行了测试,并且可以工作。
已编辑的SQL:
SELECT cl.eventID, m.playerID,
(SELECT
SUM(cl2.points)
FROM
championshipleaderboard cl2
WHERE
cl2.playerID = pr.playerID
AND cl2.eventID = cl.eventID
ORDER BY cl2.points DESC
LIMIT 3) AS top_x_sum
FROM championshipleaderboard cl, members m
WHERE cl.playerID = m.playerID
GROUP BY CONCAT(cl.eventID, m.playerID);
答案 4 :(得分:0)
使用rank
实时测试:https://www.db-fiddle.com/f/4ufuFAXKf7mi5yefNQqoXM/2
with ranking as
(
select
player,
rank() over(partition by player order by points desc) as xrank,
points
from tbl
)
,pick3 as
(
select player, sum(points) as best3
from ranking
where xrank <= 3
group by player
)
select
t.player,
sum(if(t.eventid = 1, t.points,0)) as event1,
sum(if(t.eventid = 2, t.points,0)) as event2,
sum(if(t.eventid = 3, t.points,0)) as event3,
sum(if(t.eventid = 4, t.points,0)) as event4,
p.best3
from tbl t
join pick3 p on t.player = p.player
group by t.player
输出:
| player | event1 | event2 | event3 | event4 | best3 |
| ------ | ------ | ------ | ------ | ------ | ----- |
| 1 | 25 | 15 | 20 | 20 | 65 |
| 2 | 20 | 13 | 12 | 10 | 45 |
答案 5 :(得分:0)
MySQL 5.7
实时测试:https://www.db-fiddle.com/f/4ufuFAXKf7mi5yefNQqoXM/15
select
t.player,
sum(case when t.eventid = 1 then t.points end) as event1,
sum(case when t.eventid = 2 then t.points end) as event2,
sum(case when t.eventid = 3 then t.points end) as event3,
sum(case when t.eventid = 4 then t.points end) as event4,
sum(
case when t.points >= (
select best3.points
from tbl best3
where best3.player = t.player
order by best3.points desc
limit 1 offset 2 -- offset starts with 0. so 2 is the third
) then
t.points
end
) as best3
from tbl t
group by t.player;
输出:
| player | event1 | event2 | event3 | event4 | best3 |
| ------ | ------ | ------ | ------ | ------ | ----- |
| 1 | 25 | 15 | 20 | 20 | 65 |
| 2 | 20 | 13 | 12 | 10 | 45 |