ではなくに参加team
したいと思います。テーブルには外部キーである(または) 列があると思います。user
game
user
team_id
team
references team(id)
クエリに必要な変更は 1 行だけだと思います。これを変更するだけです:
JOIN team AS t ON g.away=t.id OR g.home=t.id
に
JOIN team AS t ON t.id = u.team
問題を解決するにはこれで十分です。
しかし、クエリの書き方は少し異なります。このようなもの:
SELECT u.name
, t.name AS team
, SUM(
CASE WHEN (g.awayScore > g.homeScore AND g.away=t.id)
OR (g.homeScore > g.awayScore AND g.home=t.id)
THEN 1 ELSE 0 END
) AS wins
, SUM(
CASE WHEN (g.awayScore < g.homeScore AND g.away=t.id)
OR (g.homeScore < g.awayScore AND g.home=t.id)
THEN 1 ELSE 0 END
) AS losses
FROM user u
JOIN team t ON t.id = u.team
JOIN game g ON g.away = t.id OR g.home = t.id
GROUP
BY u.name
, t.name
ノート
まず、ユーザー テーブルから始めます。これが、私たちが本当に返したいものです。(どのゲームにも参加していないチームのユーザーにゼロを返したい場合は、OUTER JOIN の実行を検討します。私は常に LEFT JOINS を記述します。)
次に、各ユーザーに関連付けられたチームを取得します。
その後、ゲームに参加します。ここでは少し注意が必要です。ゲームの行を 2 倍にするためです。1 つはアウェイ チームに合わせて、もう 1 つはホーム チームに合わせます。また、チームのユーザーごとに 1 つずつ、行を乗算します。しかし、それらをすべて合計するので、それが必要です。
このようにクエリを記述すると、ユーザーを返すことなく、チームごとにスコアを取得するだけでかなり簡単になります。
SELECT t.name AS team
, SUM(
CASE WHEN (g.awayScore > g.homeScore AND g.away=t.id)
OR (g.homeScore > g.awayScore AND g.home=t.id)
THEN 1 ELSE 0 END
) AS wins
, SUM(
CASE WHEN (g.awayScore < g.homeScore AND g.away=t.id)
OR (g.homeScore < g.awayScore AND g.home=t.id)
THEN 1 ELSE 0 END
) AS losses
FROM team t
JOIN game g ON g.away = t.id OR g.home = t.id
GROUP
BY t.name
大規模なセットの場合、それはかなり多数の行になる可能性があり、チームの各ユーザーに対して各チームの行が複製されるため、最初のクエリで多くの行が生成される可能性があります。
したがって、別のアプローチとして、最初にチームのスコアを計算してから、ユーザーに参加することもできます。しかし、それには派生テーブルが必要になります。これは、一時的な MyISAM テーブルを生成し、そこからクエリを実行するためのオーバーヘッドです。(数十人のユーザーがいるトラック チームの場合、これはより効率的かもしれません。しかし、2 人のチーム (ビーチ バレーボール?) の場合は、パフォーマンスが向上しない可能性があります。
上記のチーム スコア クエリを使用すると、それを括弧で囲み、テーブルのように使用できます。team テーブルの id 列も含めたいので、外側のクエリで users テーブルに結合できます。
SELECT u.name
, s.name AS team
FROM user u
JOIN ( SELECT t.id
, t.name
, SUM(
CASE WHEN (g.awayScore > g.homeScore AND g.away=t.id)
OR (g.homeScore > g.awayScore AND g.home=t.id)
THEN 1 ELSE 0 END
) AS wins
, SUM(
CASE WHEN (g.awayScore < g.homeScore AND g.away=t.id)
OR (g.homeScore < g.awayScore AND g.home=t.id)
THEN 1 ELSE 0 END
) AS losses
FROM team t
JOIN game g ON g.away = t.id OR g.home = t.id
GROUP BY t.id, t.name
) s
ON s.id = u.team
インライン ビュー (s のエイリアスが割り当てられます) は、基本的に前の「チーム スコア」クエリと同じです。team.id 列を含めて、外側のクエリでユーザー テーブルに結合できるようにします。
-- 別の代替アプローチ:
SELECT u.name
, t.name AS team
, SUM(g.wins) AS wins
, SUM(g.losses) AS losses
FROM user u
JOIN team t ON t.id = u.team
JOIN ( SELECT gh.home AS team
, SUM(IF(gh.homeScore > gh.awayScore,1,0)) AS wins
, SUM(IF(gh.homeScore < gh.awayScore,1,0)) AS losses
FROM game gh
GROUP BY gh.home
UNION ALL
SELECT ga.away AS team
, SUM(IF(ga.awayScore > ga.homeScore,1,0)) AS wins
, SUM(IF(ga.awayScore < ga.homeScore,1,0)) AS losses
FROM game ga
GROUP BY ga.away
) g
ON g.team = t.id
GROUP
BY u.name
, t.name
インライン ビュー (上記で g のエイリアスが割り当てられています) は、ホームの勝敗とアウェイの勝敗を別々に計算し、それらを連結しています。home_wins、home_losses、away_wins、および away_losses を個別に返したい場合は、クエリを少し調整できます。そして、これらを外側のクエリに追加して、合計の勝敗を取得できます。