2015-04-02 2 views
1

У меня есть следующие таблицы в моей БДИспользование MySQL GROUP_CONCAT и где

EVENT

ID, TITLE, ... 

ГОЛОСОВ

ID, TYPE, ID_EVENT 

КОММЕНТАРИИ

ID, COMMENT, ID_EVENT 

ДАТА

ID, DATE, ID_EVENT 

Один EVENT имеет много действий, имеет много комментариев и имеет много дат.

Я использую следующий запрос для извлечения информации из таблицы EVENTS, и для каждого события извлекается количество голосов, количество комментариев и каждая из дат. Для событий с одной даты их = завтра (2015-04-03)

 SELECT events.id, 
       events.title, 
       GROUP_CONCAT(dates.date) AS dates, 
       COUNT(distinct votes.id) AS votes, 
       COUNT(distinct comments.id) AS comments 
     FROM events 
     LEFT JOIN dates on dates.post_id = events.id 
     LEFT JOIN votes on votes.post_id = events.id AND votes.type = 1 
     LEFT JOIN comments on comments.votes_id = votes.id 
     WHERE dates.date = CURDATE() + INTERVAL 1 DAY 
     GROUP BY events.id 

Результат выглядит следующим образом

id title dates       votes comment 
33 Event33 2015-04-03,2015-04-03,2015-04-03 4  0 
39 Event39 2015-04-03      9  1 

Почему столбец дат повторяет ту же дату (завтра) ??? Даты Event33 должны быть 2015-04-01, 2015-04-02, 2015-04-03.

Что не так?

+0

Вы, вероятно, хотите 'GROUP BY events.id' и использовать' distinct' внутри ' GROUP_CONCAT() ', как вы это делали с' COUNT() ' –

+0

извините ypercube, группа была ошибкой письма. Я его редактирую. Запрос отлично работает без предложения WHERE для перечисления всех событий. Но не работает, когда я добавляю, где предложение фильтровать по дате – user3670128

ответ

0

Вы хотите, чтобы события, имеющие один с их датами завтра. Ваш запрос делает это, но он также отключает все остальные даты.

Вам необходимо дополнительное соединение или подзапрос EXISTS.

Кроме того, необходимо DISTINCT на GROUP_CONCAT(), так же, как вы использовали его в COUNT() агрегате:

SELECT events.id, 
     events.title, 
     GROUP_CONCAT(DISTINCT dates.date) AS dates, 
     COUNT(DISTINCT votes.id) AS votes, 
     COUNT(DISTINCT comments.id) AS comments 
FROM events 
    LEFT JOIN dates ON dates.post_id = events.id 
    LEFT JOIN votes ON votes.post_id = events.id AND votes.type = 1 
    LEFT JOIN comments ON comments.votes_id = votes.id 
WHERE EXISTS 
     (SELECT 1 
     FROM dates AS dd 
     WHERE dd.date = CURDATE() + INTERVAL 1 DAY 
      AND dd.post_id = events.id 
    ) 
GROUP BY events.id ; 

Другой способ будет с помощью встроенных подзапросов. Нет необходимости в GROUP BY или DISTINCT. Незначительный недостаток в вашем случае, является то, что присоединиться к comments через votes, поэтому один подзапрос имеет дополнительный присоединиться:

SELECT e.id, 
     e.title, 
     (SELECT GROUP_CONCAT(d.date) 
      FROM dates AS d 
      WHERE d.post_id = e.id 
     ) AS dates, 
     (SELECT COUNT(v.id) 
      FROM votes AS v 
      WHERE v.post_id = e.id AND v.type = 1 
     ) AS votes, 
     (SELECT COUNT(c.id) 
      FROM comments AS c 
      JOIN votes AS v ON c.votes_id = v.id 
      WHERE v.post_id = e.id AND v.type = 1 
     ) AS comments 
FROM events AS e 
WHERE EXISTS 
     (SELECT 1 
     FROM dates AS dd 
     WHERE dd.date = CURDATE() + INTERVAL 1 DAY 
      AND dd.post_id = events.id 
    ) ; 
+0

Это отлично работает для меня! спасибо ypercube – user3670128

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