[英]MySQL count rows on multiple grouped columns
我的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
我很確定有一種簡單的方法可以得到結果,但我無法理解這一點。
您可以使用條件聚合來完成此任務。 為此,您在玩家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小提琴示例。
重要的是要注意,此示例假設玩家至少有一個目標或至少一個助手。 如果你想要兩個都沒有的玩家,你可以使用外部聯接。
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
另一種解決方法是CROSS JOIN
玩家和目標,然后使用CASE..WHEN
映射計算Scorers
和Assists
上的交叉點數量。 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;
有幾種方法可以解決這個問題。 我相信這樣的事情會很好:
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
以下是實現此目的的簡單方法:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.