簡體   English   中英

MySQL計算多個分組列的行數

[英]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映射計算ScorersAssists上的交叉點數量。 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;

SqlFiddle在這里

有幾種方法可以解決這個問題。 我相信這樣的事情會很好:

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

http://sqlfiddle.com/#!9/7b135a/5

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM