使用mysql GROUP_CONCAT和WHERE

时间:2015-04-02 19:59:01

标签: mysql group-concat

我的数据库中有以下表格

EVENT

ID, TITLE, ...

票数

ID, TYPE, ID_EVENT

评论

ID, COMMENT, ID_EVENT

DATES

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。

有什么问题?

1 个答案:

答案 0 :(得分: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 BYDISTINCT。在您的情况下,一个小缺点是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
      ) ;