我想你想加入team
,user
而不是game
。我希望该user
表有一个team_id
(or team
) 列,它是一个外键references team(id)
。
我认为您的查询中唯一需要更改的是一行。只需更改此:
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。)
接下来,我将让团队与每个用户相关联。
然后,我会加入游戏。这里有点棘手,因为你要加倍比赛的行数,一个与客队匹配,一个与主队匹配。这也会增加行数,团队中的每个用户一个。但我们需要它,因为我们要把它们全部总结起来。
以这种方式编写查询可以很容易地按团队获取分数,而无需返回用户:
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 表并从中查询的开销。(如果这是一个有数十名用户的田径队,这可能会更有效率。但如果它的两个团队(沙滩排球?)它可能不会提高性能。
如果我们采用上面的团队分数查询,我们可以将其包装在括号中并像表格一样使用它。我们还希望包含 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,可以稍微调整查询。并且这些可以在外部查询中加在一起以获得总赢和输。