我在MySQL表上有以下结构:
-------------------------------------------
Goal
-------------------------------------------
GoalID | GameID | ScorerID | AssistID
-------------------------------------------
1 1 1 2
2 1 2 3
3 1 2 null
4 1 3 2
5 2 1 3
6 2 1 null
----------------------
Player
----------------------
PlayerID | LastName
----------------------
1 AB
2 CD
3 EF
现在,我想要实现的目标如下:
-------------------------------------------
GameID | Player | Goals | Assists
-------------------------------------------
1 AB 1 0
1 CD 2 2
1 EF 1 1
2 AB 2 0
2 EF 0 1
这是我尝试的但它给了我错误的结果:
SELECT Goal.GoalID,
Goal.GameID,
COUNT(Scorer.PlayerID) AS Goals,
COUNT(Assist.PlayerID) AS Assists,
Player.LastName AS Player
FROM Goal
LEFT JOIN Player Player
ON Player.PlayerID = Goal.ScorerID
OR Player.PlayerID = Goal.AssistID
LEFT JOIN Player Scorer
ON Scorer.PlayerID = Goal.ScorerID
LEFT JOIN Player Assist
ON Assist.PlayerID = Goal.AssistID
GROUP BY Player,
Goal.GameID
ORDER BY Goal.GameID,
Goal.GoalID
我非常确定这是获得结果的简单方法,但我无法理解这一点。
答案 0 :(得分:3)
您可以使用条件聚合来完成此任务。为此,您在玩家ID与scorerid或辅助ID匹配的条件下加入玩家和目标表,然后获得玩家ID在分数或辅助列中的情况的SUM(),并最终分组gameID和playerID。像这样:
SELECT g.gameID, p.lastName AS Player, SUM(g.scorerID = p.playerID) AS goals, SUM(g.assistID = p.playerID) AS assists
FROM goal g
JOIN player p ON p.playerID = g.scorerID OR p.playerID = g.assistID
GROUP BY g.gameID, p.playerID;
以下是SQL Fiddle示例。
重要的是要注意,此示例假设玩家至少有一个目标或至少一个助手。如果你想要两个都没有的玩家,你可以使用外部联接。
答案 1 :(得分:2)
http://sqlfiddle.com/#!9/88479/7
SELECT g.GameID,
p.LastName,
SUM(IF(p.id=g.ScorerID,1,0)) as Goals,
SUM(IF(p.id=g.AssistID,1,0)) as Assists
FROM goal g
LEFT JOIN player p
ON p.id = g.ScorerID
OR p.id = g.AssistID
GROUP BY g.GameID,p.id
答案 2 :(得分:1)
解决此问题的另一种方法是CROSS JOIN
玩家和目标,然后使用Scorers
映射计算Assists
和CASE..WHEN
上的交叉点数量。 HAVING
用于消除那些没有为得分线做出贡献的球员。
SELECT
Goal.GameID,
Player.LastName AS Player,
SUM(CASE WHEN Goal.ScorerId = Player.PlayerID THEN 1 ELSE 0 END) AS Goals,
SUM(CASE WHEN Goal.AssistId = Player.PlayerID THEN 1 ELSE 0 END) AS Assists
FROM Goal
CROSS JOIN Player
GROUP BY Player.LastName,
Goal.GameID
HAVING Goals > 0 OR Assists > 0
ORDER BY Goal.GameID,
Player.LastName;
答案 3 :(得分:0)
有几种方法可以解决这个问题。我相信这样的事情会很好:
SELECT
GameId,
Lastname,
Sum(Goals) as Goals,
Sum(Assists) as Assists
FROM
(
SELECT GameID, Player.Lastname, 1 as Goals, 0 as Assists
FROM Goal
INNER JOIN Player ON goal.scorerID = Player.PlayerID
UNION
SELECT GameID, Player.Lastname, 0 as Goals, 1 as Assists
FROM Goal
INNER JOIN Player ON goal.AssistID = Player.PlayerID
) Games
GROUP BY GameID, LastName
答案 4 :(得分:0)
这是实现这一目标的非常简单的方法:
select GameId, LastName, goals, assist
from
(
select GameId, player, sum(goals) as goals, sum(assist) as assist
from
(
select GameId, ScorerId as player, count(*) as goals, 0 as assist
from Goal
group by GameId, ScorerId
union all
select GameId, AssistId, 0 as goals, count(*) as assist
from Goal
where AssistId is not null
group by GameId, AssistId
) as q
group by GameId, player
) as q2
inner join
Player as t
on (q2.player=t.PlayerId)
order by GameId, LastName