COUNT + GROUP_CONCAT с GROUP BY возвращает неправильные значения - PullRequest
0 голосов
/ 02 мая 2018

Приведенный ниже запрос направлен на получение списка событий, содержащих имена событий, COUNT пользователей, назначенных на событие, COUNT оставленных комментариев и GROUP_CONCAT имен пользователей, назначенных на событие.

Все работает нормально, если я оставляю присоединение к таблицам комментариев или заданий, но не к обоим!

Если я присоединяюсь к обоим счетам, все числа умножаются друг на друга. Если одно событие имеет 3 комментария и 5 пользователей назначило количество комментариев, а количество пользователей будет 5 x 3 = 15. Также GROUP_CONCAT будет возвращать каждое имя пользователя 3 раза, например: Joe, Joe, Joe, Mike, Mike, Mike,... вместо Joe, Mike,...

Я бы хотел, чтобы кто-нибудь объяснил почему. И выложите решение :) 1009 *

SELECT 
    e.id_eve,
    e.title_eve,
    v.name_ven,
    COUNT(a.ideve_ass) AS count_ass,
    COUNT(c.ideve_com) AS count_com,
    GROUP_CONCAT(u.firstname_usr) AS users_eve
FROM 
    rsevents_eve AS e
    LEFT JOIN venues_ven v ON e.idven_eve = v.id_ven
    LEFT JOIN rscomments_com c ON c.ideve_com = e.id_eve
    LEFT JOIN rsassignments_ass a ON a.ideve_ass = e.id_eve
    LEFT JOIN users_usr u ON u.id_usr = a.idusr_ass
GROUP BY 
    e.id_eve

1 Ответ

0 голосов
/ 02 мая 2018

Вы агрегируете по разным измерениям, поэтому вы получаете декартово произведение для каждого события.

Есть несколько решений. Одним из них является предварительная агрегация каждой таблицы. Я собираюсь предложить альтернативные, коррелированные подзапросы:

SELECT e.id_eve, e.title_eve, v.name_ven,
       (SELECT COUNT(*)
        FROM rsassignments_ass a 
        WHERE a.ideve_ass = e.id_eve
       ) as count_ass,
       (SELECT COUNT(*)
        FROM rscomments_com c 
        WHERE c.ideve_com = e.id_eve
       ) as count_com,
       (SELECT GROUP_CONCAT(u.firstname_usr)
        FROM users_usr u JOIN
             rsassignments_ass a 
             ON u.id_usr = a.idusr_ass
        WHERE a.ideve_ass = e.id_eve
       ) as users_eve
FROM rsevents_eve e LEFT JOIN
     venues_ven v
     ON e.idven_eve = v.id_ven;

Третий способ исправить это - поместить DISTINCT в каждый COUNT() и GROUP_CONCAT(). Тем не менее, приведенный выше способ должен быть наиболее эффективным, если у вас есть индексы для ключей JOIN.

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