PostgreSQLのバックグラウンドはありませんが、これが機能するかどうかを確認します。
これを単純化することから始めます。最初にプレーヤーごとの合計スコアを返すクエリを記述します。
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
次に、そのデータセットをプレーヤーに参加させて、グループを見つけます。
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
これで、すべてのプレーヤー、合計スコア、およびグループができました。グループごとに勝者を特定したいですか? ランキング を使用できます これを行うための関数:
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
ここで、WHERE
を使用して、各グループ(ランク=1)の上位のものを選択します。
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
複雑に見えますか?はい。ただし、最終結果が少しずつ提供されていることがわかります。この各ステップは「サブテーブル」であり、各ポイントでデータを実行および監視できます。