2009-10-20 8 views
1

У меня есть база данных mysql, которая отслеживает статистику хоккея. То, что я хотел бы сделать, - в одном запросе получить количество целей и ассистентов, набранных каждым игроком, а также количество игр, в которые они играли. Я использую Zend Framework и запрос, который я создал заключается в следующем:Подсчет строк в нескольких таблицах

SELECT `p`.*, 
     `pxt`.`jersey_number`, 
     count(pxg.player_x_game_id) AS `games`, 
     count(goals.scoring_id) AS `goals`, 
     count(assists.scoring_id) AS `assists` 
FROM `players` AS `p` 
INNER JOIN `players_x_teams` AS `pxt` ON p.player_id = pxt.player_id 
INNER JOIN `teams_x_seasons` AS `txs` ON pxt.team_id = txs.team_id 
INNER JOIN `seasons` AS `s` ON txs.season_id = s.season_id 
INNER JOIN `games` AS `g` ON g.season_id = s.season_id 
INNER JOIN `players_x_games` AS `pxg` ON pxg.game_id = g.game_id 
            AND pxg.player_id = p.player_id 
LEFT JOIN `scoring` AS `goals` ON goals.game_id = g.game_id 
           AND goals.scorer_id = p.player_id 
LEFT JOIN `scoring` AS `assists` ON assists.game_id = g.game_id 
           AND (assists.assist1_id = p.player_id OR assists.assist2_id = p.player_id) 
WHERE (pxt.team_id = 1) 
    AND (txs.season_id = '23') 
    AND (pxt.date_added <= s.end_date OR pxt.date_added is null) 
    AND (pxt.date_removed >= s.start_date OR pxt.date_removed is null) 
GROUP BY `p`.`player_id` 

Этот запрос возвращает мне данные, но мои подсчеты отключены.

+-----------+---------------+-------+-------+---------+ 
| player_id | jersey_number | games | goals | assists | 
+-----------+---------------+-------+-------+---------+ 
|   2 | 3    |  7 |  1 |  3 | 
|   3 | 19   |  6 |  1 |  0 | 
|   8 | 8    |  7 |  3 |  2 | 
|   9 | 11   | 13 | 10 |  8 | 
|  11 | 96   |  6 |  1 |  3 | 
|  12 | 14   |  6 |  0 |  3 | 
|  13 | 7    |  6 |  0 |  1 | 
|  115 | 39   |  9 |  6 |  2 | 
|  142 | 68   |  6 |  0 |  1 | 
|  143 | 30   |  6 |  0 |  0 | 
|  150 | 41   | 11 | 11 |  5 | 
|  185 | 17   |  6 |  6 |  3 | 
|  225 | 97   |  4 |  1 |  3 | 
+-----------+---------------+-------+-------+---------+ 

В этом наборе большинство игр, которые должны присутствовать являются 6, но как вы можете видеть, я получаю дополнительные услуги. Если я отредактирую свой запрос, чтобы удалить цели и помочь полям, то количество моих игр будет правильным. На самом деле, если я только выбираю одну из моих подсчитанных строк, я всегда получаю правильные подсчеты, но как только я добавляю второй или третий счет, мои числа начинают перекоситься. Что я делаю не так?

ответ

3

Поскольку вы выполняете несколько объединений, каждая из которых может соответствовать нескольким строкам и переносить на следующее соединение, вы должны добавить distinct в свой count. Попробуйте следующее:

SELECT `p`.*, 
     `pxt`.`jersey_number`, 
     count(distinct pxg.player_x_game_id) AS `games`, 
     count(distinct goals.scoring_id) AS `goals`, 
     count(distinct assists.scoring_id) AS `assists` 
FROM `players` AS `p` 
INNER JOIN `players_x_teams` AS `pxt` ON p.player_id = pxt.player_id 
INNER JOIN `teams_x_seasons` AS `txs` ON pxt.team_id = txs.team_id 
INNER JOIN `seasons` AS `s` ON txs.season_id = s.season_id 
INNER JOIN `games` AS `g` ON g.season_id = s.season_id 
INNER JOIN `players_x_games` AS `pxg` ON pxg.game_id = g.game_id 
            AND pxg.player_id = p.player_id 
LEFT JOIN `scoring` AS `goals` ON goals.game_id = g.game_id 
           AND goals.scorer_id = p.player_id 
LEFT JOIN `scoring` AS `assists` ON assists.game_id = g.game_id 
           AND (assists.assist1_id = p.player_id OR assists.assist2_id = p.player_id) 
WHERE (pxt.team_id = 1) 
    AND (txs.season_id = '23') 
    AND (pxt.date_added <= s.end_date OR pxt.date_added is null) 
    AND (pxt.date_removed >= s.start_date OR pxt.date_removed is null) 
GROUP BY `p`.`player_id` 
3

Возможно, вам нужно count(DISTINCT pxg.player_x_game_id) ...? Похоже, что в этом гумунном мегаягоне могут быть дубликаты (что я признаю, что на самом деле не потратили время на полное воспроизведение!)

+0

Отличие это. Я думал, что я бы не допустил дубликатов с моей логикой соединения, но, наверное, я что-то пропустил. Благодарю. –

+0

@Rob, пожалуйста! –

Смежные вопросы