MySQL query - join 3 tables together, group by one column and count for the other 2

試著忘記壹切 提交于 2021-02-08 07:33:30

问题


Here are examples of the 3 tables I'm working with.


    Teams
    +----+------+
    | id | name |
    +----+------+
    |  1 | abc  |
    |  2 | def  |
    |  3 | ghi  |
    +----+------+


    Members
    +----+-----------+----------+---------+
    | id | firstname | lastname | team_id |
    +----+-----------+----------+---------+
    |  1 | joe       | smith    |       1 |
    |  2 | jared     | robinson |       1 |
    |  3 | sarah     | cole     |       3 |
    |  4 | jaci      | meyers   |       2 |
    +----+-----------+----------+---------+


    Goals
    +----+-----------+
    | id | member_id |
    +----+-----------+
    |  1 |         3 |
    |  2 |         2 |
    |  3 |         2 |
    |  4 |         3 |
    |  5 |         1 |
    +----+-----------+
    


And I'm trying to get a query that outputs something like this ...


    Output
    +--------+----------------+-------------+
    | t.name | Count(members) | Count(goals)|
    +--------+----------------+-------------+
    | abc    |              2 |           3 |
    | def    |              1 |           2 |
    | ghi    |              1 |           0 |
    +--------+----------------+-------------+
    


This is the closest I've come, but when I use the group by in the subquery I get "Subquery returns more than 1 row".

select t.name, count(*), 
    (select count(*)
    from teams t 
    inner join members m on m.team_id = t.id
    group by t.id)
from teams t 
inner join members m on m.team_id = t.id 
inner join goals g on g.member_id = m.id
group by t.id

回答1:


Based on my understanding, here is the query that I come up with:


    SELECT name, membersCount, IFNULL(totalCount, 0) goalsCount FROM
    (
      SELECT m.team_id, SUM(innerQuery.goalsCount) totalCount
      FROM (
        SELECT m.id memberId, COUNT(*) goalsCount
        FROM Members m
        JOIN Goals g
        ON m.id = g.member_id
        GROUP BY member_id
      ) innerQuery
      JOIN Members m
      ON innerQuery.memberId = m.id
      GROUP BY m.team_id
    ) inner_1
    RIGHT JOIN 
    (
      SELECT t.id, t.name, COUNT(*) membersCount
      FROM Teams t
      JOIN Members m
      ON t.id = m.team_id
      GROUP BY team_id
    ) inner_2
    ON inner_1.team_id = inner_2.id

The breakdown of the query:

#1. Get the member ID with its associated goals count (innerQuery)


SELECT m.id memberId, COUNT(*) goalsCount
    FROM Members m
    JOIN Goals g
    ON m.id = g.member_id
    GROUP BY member_id

#2. Get the team id for with the total SUM of the goals (inner_1)


     SELECT m.team_id, SUM(innerQuery.goalsCount) totalCount
      FROM (
          .... Sub-query in step 1
      ) innerQuery
      JOIN Members m
      ON innerQuery.memberId = m.id
      GROUP BY m.team_id

#3. Get total members count per team (inner_2)


    SELECT t.id, t.name, COUNT(*) membersCount
      FROM Teams t
      JOIN Members m
      ON t.id = m.team_id
      GROUP BY team_id

#4. RIGHT JOIN inner_1 and inner_2 (since there will be NULL) and use IFNULL to check and replace that 0


    SELECT name, membersCount, IFNULL(totalCount, 0) goalsCount FROM
    (
     .... Sub-query in step 2
    ) inner_1
    RIGHT JOIN 
    (
      .... Sub-query in step 3
    ) inner_2
    ON inner_1.team_id = inner_2.id



来源:https://stackoverflow.com/questions/7641928/mysql-query-join-3-tables-together-group-by-one-column-and-count-for-the-othe

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!