Использование подсчета в соединении с MySQL

Я пытался написать sql-запрос, чтобы получить статистику от bugzilla. Вот запрос

select bugs.bug_id AS bug_id, 
       COUNT(map_pingpong.bug_when) AS re_open, 
       MAX(map_closetime.bug_when) AS closed_date 
  from bugs 
         LEFT JOIN bugs_activity AS map_pingpong 
                 ON ((map_pingpong.bug_id = bugs.bug_id 
                        and map_pingpong.fieldid=15)) 
         LEFT JOIN bugs_activity AS map_closetime 
                 ON ((bugs.bug_id = map_closetime.bug_id 
                        and map_closetime.fieldid=8 
                        and bugs.bug_status = 'CLOSED' )) 
 where (bugs.assigned_to = 480) 
 GROUP BY bugs.bug_id 
 ORDER BY bug_id;

Итак, запрос должен возвращать две вещи

1) Количество событий 2) Дата события

Поэтому, когда я разбиваю запрос на два разных запроса, они возвращают правильные значения. Если я запускаю его, как указано выше, значения счетчика неверны (хотя дата верна). Я не должен запускать два соединения на одной таблице? или count не должен быть там, когда вы используете join ?


person user3468877    schedule 23.10.2014    source источник
comment
Вы не можете запустить SQL во фрагменте кода, это только для Javascript.   -  person Barmar    schedule 23.10.2014
comment
Когда вы запускаете два соединения, вы получаете декартово произведение обеих таблиц, и count() будет подсчитывать строки в произведении.   -  person Barmar    schedule 23.10.2014
comment
Вы можете решить эту проблему, используя COUNT(DISTINCT map_pingpong.some_unique_column)   -  person Barmar    schedule 23.10.2014
comment
Извините за добавление фрагмента кода. Я думал, что таким образом запрос будет более удобным для чтения :)   -  person user3468877    schedule 23.10.2014


Ответы (1)


Как сказал Бармар, вам нужно отделить наборы результатов, чтобы получить правильные подсчеты:

SELECT 
    bugs.bug_id AS bug_id, 
    map_pingpong.cnt AS re_open, 
    map_closetime.mx AS closed_date
FROM bugs 
    LEFT JOIN (
        SELECT bug_id, COUNT(bug_when) AS cnt
        FROM bugs_activity
        WHERE fieldid = 15
        GROUP BY bug_id
    ) AS map_pingpong ON map_pingpong.bug_id = bugs.bug_id
    LEFT JOIN (
        SELECT ba.bug_id, MAX(ba.bug_when) AS mx
        FROM bugs_activity ba JOIN bugs ON bugs.bug_status = 'CLOSED' AND ba.bug_id = bug.bug_id AND bugs.assigned_to = 480
        WHERE ba.fieldid = 8
        GROUP BY ba.bug_id
    ) AS map_closetime ON bugs.bug_id = map_closetime.bug_id
WHERE bugs.assigned_to = 480
GROUP BY bugs.bug_id 
ORDER BY bug_id;

Поскольку это правильно с функциональной точки зрения, это может быть полной катастрофой с точки зрения производительности, поэтому будьте осторожны...

person Sebas    schedule 23.10.2014
comment
Большое спасибо, бармар и семас. Теперь я понял проблему. Я предполагал, что count применим только для соответствующего случая JOIN. - person user3468877; 23.10.2014