【问题标题】:How do I SELECT a SUM of multiple GROUP BY rows?如何选择多个 GROUP BY 行的总和?
【发布时间】:2016-04-23 09:09:19
【问题描述】:

我有一个球员与比赛的关系表以及他们在每场比赛中的得分。我正在尝试做一个选择,在其中我得到一个不同的球员名单,他们的总得分以及他们参加过的所有球队的总得分。由于一切都是针对单个玩家的,我不知道如何仅针对单个列摆脱 GROUP BY 范围。对于下面的例子,我只会说每支球队只有两名球员。在实际的数据库中,如果重要的话,每个团队都有五个。谢谢大家。

表“匹配”:

match_id | winning_team |

56427859 |            0 |
56427860 |            1 |
56427861 |            1 |
56427862 |            0 |
56427863 |            1 |

etc...

表格“match_players”:

match_id | team | player_id | points |

56427859 |    0 |        10 |      3 |
56427859 |    0 |        33 |      1 |
56427859 |    1 |        26 |      0 |
56427859 |    1 |        39 |      2 |
56427860 |    0 |        23 |      1 |
56427860 |    0 |        33 |      3 |
56427860 |    1 |        18 |      1 |
56427860 |    1 |        10 |      4 |

etc...

期望的结果:

player_id | match_count | total_points | team_total_points | <- This should be
                                                                the total of all
       10 |           2 |            7 |                 9 |    points scored by
       18 |           1 |            1 |                 5 |    the player and
       23 |           1 |            1 |                 4 |    his teammates
       26 |           1 |            0 |                 2 |    in all matches.
       33 |           2 |            4 |                 8 |
       39 |           1 |            2 |                 2 |

查询:

SELECT
    p.player_id,
    COUNT(*) AS match_count,
    SUM(CASE WHEN mp.team = m.winning_team THEN 1 ELSE 0 END) AS win_count,
    SUM(points) AS total_points,
    [________________________________________] AS team_total_points
FROM matches m
INNER JOIN match_players mp ON m.match_id = mp.match_id
INNER JOIN players p ON mp.player_id = p.player_id
GROUP BY player_id
ORDER BY player_id

编辑:

“球队”列简单地定义了红色或蓝色、主场或客场等。球员可以在不同的比赛中加入不同的球队。并且玩家可以在比赛之间交换球队,比如课间躲避球。

【问题讨论】:

  • 如何定义“团队”?
  • 对,对不起。只有两个。基本上,团队只是意味着主场和客场。玩家可以随时加入任何团队。就像躲避球一样。我会编辑我的帖子。
  • 编写一个子查询来计算每个球员的球队总数。将该子查询与您的主查询连接起来,并将总数填空。
  • 我尝试了类似的方法,但由于某种原因我无法获得队友的分数。括号内的任何“(SELECT SUM(points)...”都不会返回每个特定玩家的积分的总和,而其他人的积分都不是由于 group by 吗?对不起,我对 SQL 的理解很差。
  • @Barmar - 哦,你的意思是像 Vitto 在他的帖子中展示的那样。好的,我会试试的。谢谢。

标签: mysql sql


【解决方案1】:

以下查询将计算与每个玩家在同一团队中的所有玩家的总分。

SELECT p1.player_id, SUM(p2.total_points) AS team_total_points
FROM match_players AS p1
JOIN (SELECT match_id, team, SUM(points) as total_points
      FROM match_players
      GROUP BY match_id, team) AS p2
ON p1.match_id = p2.match_id AND p1.team = p2.team
GROUP BY p1.player_id

然后您可以将其与原始查询结合起来以添加团队总数。

SELECT
    p.player_id,
    COUNT(*) AS match_count,
    SUM(CASE WHEN mp.team = m.winning_team THEN 1 ELSE 0 END) AS win_count,
    SUM(points) AS total_points,
    mp2.team_total_points
FROM matches m
INNER JOIN match_players mp ON m.match_id = mp.match_id
INNER JOIN players p ON mp.player_id = p.player_id
INNER JOIN 
    (SELECT p1.player_id, SUM(p2.total_points) AS team_total_points
     FROM match_players AS p1
     JOIN (SELECT match_id, team, SUM(points) as total_points
           FROM match_players
           GROUP BY match_id, team) AS p2
     ON p1.match_id = p2.match_id AND p1.team = p2.team
     GROUP BY p1.player_id) AS mp2 ON mp2.player_id = p.player_id
GROUP BY player_id
ORDER BY player_id

DEMO

【讨论】:

  • 我不敢相信我第一次尝试就做对了 :)
  • 哇,真快。是的,我刚才正在写类似的东西。之前的问题是我没有意识到您可以加入 SELECT 语句的结果。棒极了。谢谢大佬。
  • 似乎我什至可以将 total_points 从 JOIN 中提取出来并在主查询中使用它,而不是用另一个 SUM 重新计算它们,对吧?虽然 MySQL 无论如何都会优化它?
  • 是的,这可能会被简化一点,但我认为(希望)MySQL 会将其优化为同样的事情。这就是我从模块化构建中得到的。
  • 我只是想了一下...您也编写了所有代码来创建演示表。并在您提出建议后的 12 分钟内得到了有效的查询。你是速度恶魔。大声笑。
【解决方案2】:

试试这个:

SELECT player_id, COUNT(*) AS match_count, SUM(points) AS total_points, team_tot_points
FROM match_players JOIN (SELECT SUM(points) AS team_tot_points, team
                         FROM match_players
                         GROUP BY team) AS team_points
ON match_players.team = team_points.team
GROUP BY player_id

【讨论】:

  • 这不太对,因为有时球员在 0 队,有时他们在 1 队,这取决于是主场还是客场比赛。
  • @Barmar - 没错,但我可以弄清楚那部分。我会试试这个。谢谢维托。
  • @DaiBu 看我的回答。
  • 那么你如何定义同队的球员?他们是在同一场比赛中拥有同一支球队的人吗?
  • @Vitto 是的,它就是这样工作的。您可以在第 1 场比赛中担任主队,但在第 2 场比赛中担任客队。
猜你喜欢
  • 1970-01-01
  • 2014-11-22
  • 1970-01-01
  • 2021-01-15
  • 2023-04-03
  • 1970-01-01
  • 2023-01-18
  • 2021-10-30
  • 1970-01-01
相关资源
最近更新 更多