Jag har ingen PostgreSQL-bakgrund men vi får se om detta fungerar:
Jag skulle börja detta med att förenkla det genom att skriva en fråga som först returnerar den totala poängen per spelare:
SELECT player_id, SUM(score) score
FROM (
SELECT first_player as player_id, first_score as score
FROM matches
UNION ALL
SELECT second_player, second_score
FROM matches
)
GROUP BY player_id
Gå nu med datauppsättningen till spelare för att hitta grupperna:
SELECT w.player_id, p.group_id, w.score
FROM
(
SELECT player_id, SUM(score) score
FROM (
SELECT first_player as player_id, first_score as score
FROM matches
UNION ALL
SELECT second_player, second_score
FROM matches
)
GROUP BY player_id
) as w
inner join players p
on p.player_id = w.player_id
Nu har vi alla spelare, deras totala poäng och deras grupp. Vill vi identifiera vinnaren efter grupp? Vi kan använda ranking funktioner för att göra detta:
SELECT
w.player_id,
p.group_id,
w.score,
RANK() OVER (PARTITION BY p.group_id ORDER BY score DESC) as group_placement
FROM
(
SELECT player_id, SUM(score) score
FROM (
SELECT first_player as player_id, first_score as score
FROM matches
UNION ALL
SELECT second_player, second_score
FROM matches
)
GROUP BY player_id
) as w
inner join players p
on p.player_id = w.player_id
Nu väljer vi bara ut de översta i varje grupp (rank =1) med WHERE
SELECT
player_id,
group_id
FROM
(
SELECT
w.player_id,
p.group_id,
w.score,
RANK() OVER (PARTITION BY p.group_id ORDER BY score DESC) as group_placement
FROM
(
SELECT player_id, SUM(score) score
FROM (
SELECT first_player as player_id, first_score as score
FROM matches
UNION ALL
SELECT second_player, second_score
FROM matches
)
GROUP BY player_id
) as w
inner join players p
on p.player_id = w.player_id
) as gp
WHERE group_placement = 1
Ser komplicerat ut? ja, men du kan se att det slutliga resultatet tillhandahålls bit för bit. Varje steg i detta är en "undertabell" och du kan köra och observera data vid varje punkt.