Ich habe keinen PostgreSQL-Hintergrund, aber mal sehen, ob das funktioniert:
Ich würde damit beginnen, es zu vereinfachen, indem ich eine Abfrage schreibe, die zuerst die Gesamtpunktzahl pro Spieler zurückgibt:
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
Verbinden Sie nun diesen Datensatz mit Spielern, um die Gruppen zu finden:
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
Jetzt haben wir alle Spieler, ihre Gesamtpunktzahl und ihre Gruppe. Wir wollen den Gewinner nach Gruppe ermitteln? Wir können Ranking verwenden Funktionen dazu:
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
Jetzt wählen wir einfach die Besten in jeder Gruppe (Rang =1) mit WHERE
aus
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
Sieht kompliziert aus? ja, aber man sieht schon das Endergebnis wird nach und nach bereitgestellt. Jeder Schritt davon ist eine „Untertabelle“, und Sie können die Daten an jedem Punkt ausführen und beobachten.