我正在尝试将三张桌子连在一起,这有点复杂。这就是我所拥有的。在尝试选择团队名称之前,它工作正常。此外,如果有人知道如何更有效地计算胜负,那将会有所帮助。
$sql = '
SELECT u.name,
t.name AS team,
SUM(
CASE WHEN (g.awayScore > g.homeScore AND g.away=u.team)
OR (g.homeScore > g.awayScore AND g.home=u.team)
THEN 1 ELSE 0 END
) AS wins,
SUM(
CASE WHEN (g.awayScore < g.homeScore AND g.away=u.team)
OR (g.homeScore < g.awayScore AND g.home=u.team)
THEN 1 ELSE 0 END) AS losses
FROM game AS g
JOIN user AS u ON g.away = u.team OR g.home = u.team
JOIN team AS t ON g.away=t.id OR g.home=t.id
GROUP BY u.name
';
答案 0 :(得分:1)
我想您想加入team
user
,而不是game
。我希望user
表有一个team_id
(或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表的开销,然后从中查询。 (如果这是一支拥有数十名用户的赛道团队,这可能会更有效率。但如果它的两队(沙滩排球?)可能不会提高性能。
如果我们采用上面的团队分数查询,我们可以将其包装在parens中并像表格一样使用它。我们还希望包含团队表中的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,那么查询可能会稍微调整一下。这些可以在外部查询中加在一起,以获得总胜负。