请参阅另一个 Stack Overflow 问题此处,但是那里的答案不包括 group_id 3 玩家。 我尝试在 MySQL 中复制答案,但我不熟悉 PostgreSQL。任何人都可以展示如何在 MySQL 中进行操作吗?
问题是返回每组中得分最高的玩家为
winner_id
create table players (
player_id integer not null unique,
group_id integer not null
);
create table matches (
match_id integer not null unique,
first_player integer not null,
second_player integer not null,
first_score integer not null,
second_score integer not null
);
insert into players values(20, 2);
insert into players values(30, 1);
insert into players values(40, 3);
insert into players values(45, 1);
insert into players values(50, 2);
insert into players values(65, 1);
insert into matches values(1, 30, 45, 10, 12);
insert into matches values(2, 20, 50, 5, 5);
insert into matches values(13, 65, 45, 10, 10);
insert into matches values(5, 30, 65, 3, 15);
insert into matches values(42, 45, 65, 8, 4);
matches
桌子
match_id | first_player | second_player | first_score | second_score
----------+--------------+---------------+-------------+--------------
1 | 30 | 45 | 10 | 12
2 | 20 | 50 | 5 | 5
13 | 65 | 45 | 10 | 10
5 | 30 | 65 | 3 | 15
42 | 45 | 65 | 8 | 4
预期产量
group_id | winner_id
----------+-----------
1 | 45
2 | 20
3 | 40
我认为由于您无法使用其他问题的解决方案,因此您使用的是 MySQL 5.7 或更低版本。在这种情况下,您必须模拟
ROW_NUMBER/PARTITION
功能,您可以使用派生的每个玩家得分表中的 LEFT JOIN
来实现此功能,并加入比第一个表中的分数更大的 score
。任何在加入的表中没有更高分数的玩家显然具有最高分数。由于可能存在平局,因此我们从该表中取 player_id
值的最小值(当没有平局时,这没有效果)。
SELECT group_id, MIN(player_id) AS player_id
FROM (
SELECT t1.group_id, t1.player_id
FROM (
SELECT p.player_id, p.group_id,
SUM(CASE WHEN m.first_player = p.player_id THEN m.first_score
ELSE m.second_score
END) AS score
FROM players p
LEFT JOIN matches m ON m.first_player = p.player_id OR m.second_player = p.player_id
GROUP BY p.player_id, p.group_id
) t1
LEFT JOIN (
SELECT p.player_id, p.group_id,
SUM(CASE WHEN m.first_player = p.player_id THEN m.first_score
ELSE m.second_score
END) AS score
FROM players p
LEFT JOIN matches m ON m.first_player = p.player_id OR m.second_player = p.player_id
GROUP BY p.player_id, p.group_id
) t2 ON t2.group_id = t1.group_id AND t2.score > t1.score
GROUP BY t1.group_id, t1.player_id
HAVING COUNT(t2.player_id) = 0
) w
GROUP BY group_id
输出:
group_id player_id
1 45
2 20
3 40
select group_id, player_id from (
select *, row_number() over(partition by A.group_id order by score DESC, player_id ASC) as ranking
from(
select player_id, group_id, sum(case when player_id=first_player then first_score
else second_score end) as score
from players p
left join
matches m
on p.player_id=m.first_player or p.player_id=m.second_player
group by p.player_id, p.group_id)A)B
where B.ranking=1;
输出:
group_id | winner_id
----------+-----------
1 | 45
2 | 20
3 | 40