MySQL query - объедините 3 таблицы вместе, сгруппируйте по одному столбцу и посчитайте до 2 - PullRequest
1 голос
/ 04 октября 2011

Вот примеры трех таблиц, с которыми я работаю.


    <b>Teams</b>
    +----+------+
    | id | name |
    +----+------+
    |  1 | abc  |
    |  2 | def  |
    |  3 | ghi  |
    +----+------+


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


    <b>Goals</b>
    +----+-----------+
    | id | member_id |
    +----+-----------+
    |  1 |         3 |
    |  2 |         2 |
    |  3 |         2 |
    |  4 |         3 |
    |  5 |         1 |
    +----+-----------+
    


И я пытаюсь получить запрос, который выводит что-то вроде этого ...


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


Это самое близкое, что я получил, но когда я использую группу с помощью в подзапросе, я получаю «Подзапрос возвращает более 1 строки».

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 Ответ

2 голосов
/ 04 октября 2011

Исходя из моего понимания, вот запрос, который я придумаю:


    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

Разбивка запроса:

# 1. Получить идентификатор участника с соответствующим количеством целей (innerQuery)


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

# 2. Получить идентификатор команды для с общей суммой голов (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. Получить общее количество участников на команду (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. ПРАВИЛЬНОЕ СОЕДИНЕНИЕ inner_1 и inner_2 (так как будет NULL) и используйте IFNULL для проверки и замены этого 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...