Je n'ai aucune expérience PostgreSQL, mais voyons si cela fonctionne :
Je commencerais par simplifier, en écrivant une requête qui renvoie d'abord le score total par joueur :
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
Maintenant, joignez cet ensemble de données aux joueurs pour trouver les groupes :
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
Nous avons maintenant tous les joueurs, leur score total et leur groupe. On veut identifier le gagnant par groupe ? Nous pouvons utiliser le classement fonctions pour ce faire :
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
Maintenant, nous sélectionnons simplement les meilleurs dans chaque groupe (rang =1) en utilisant 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
Ça vous paraît compliqué ? oui, mais vous pouvez voir que le résultat final est fourni petit à petit. Chaque étape de ceci est une "sous-table" et vous pouvez exécuter et observer les données à chaque point.