简体   繁体   中英

MySQL: group occurrences per date

I guess this is a recurring question but I haven't found the right topic to point me in the right direction.

I have chat table which pretty much looks like:

+---------+----------------+---------------------+-----------------+
| id(int) | author(string) |   date(datetime)    | message(string) |
+---------+----------------+---------------------+-----------------+
|       1 | John           | 2016-01-01 17:18:00 | I               |
|       2 | Mary           | 2016-01-01 14:22:00 | Just            |
|       3 | John           | 2016-01-01 09:02:00 | Want            |
|       4 | John           | 2016-01-02 17:18:00 | To              |
|       5 | Mary           | 2016-01-03 18:26:00 | Say             |
|       6 | John           | 2016-01-03 10:42:00 | Hello           |
+---------+----------------+---------------------+-----------------+

What I would like to get:

+------------+------+------+
|    day     | Mary | John |
+------------+------+------+
| 2016-01-01 |    1 |    2 |
| 2016-01-02 |    0 |    1 |
| 2016-01-03 |    1 |    1 |
+------------+------+------+

Am I obligated to do a subquery in the COUNT statement ?

So far I came up with:

SELECT DATE(date) as day,
(SELECT COUNT(id) FROM chat WHERE author = 'Mary') AS 'Mary'
(SELECT COUNT(id) FROM chat WHERE author = 'John') AS 'John'
FROM chat
GROUP BY day
ORDER BY day ASC

But this is giving me the total message count per author at each row:

+------------+------+------+
|    day     | Mary | John |
+------------+------+------+
| 2016-01-01 |    2 |    4 |
| 2016-01-02 |    2 |    4 |
| 2016-01-03 |    2 |    4 |
+------------+------+------+

Just use conditional aggregation:

SELECT DATE(date) as day,
       SUM(author = 'Mary') AS Mary,
       SUM(author = 'John') AS John
FROM chat
GROUP BY day
ORDER BY day ASC

I might be wrong, but it looks for me like you search for a solution, where you have a small group of the same users? Even if it is true, I would change the logic in a way to avoid generating the query and having problems for larger amounts of users. It might not be the perfect solution for your current problem, but might help to save some time in the future. So I would use a different pattern.

As query, I would use something like this:

SELECT DATE(`date`) AS day,
  `author`,
  COUNT(`id`) AS messagecount
FROM `chat`
GROUP BY `day`, `author`
ORDER BY `day` ASC

With this you would get a result like this:

+------------+--------+--------------+
|    day     | author | messagecount |
+------------+--------+--------------+
| 2016-01-01 | Mary   |            2 |
| 2016-01-01 | John   |            4 |
| 2016-01-02 | Mary   |            2 |
| 2016-01-02 | John   |            4 |
+------------+--------+--------------+

After that, you can group the result in PHP to have the desired effect, for example generate an array like this using the date as key:

array(
  '2016-01-01' => array(
    'day' => '2016-01-01',
    'Mary' => 2,
    'John' => 4
  ),
  '2016-01-02' => array(
    'day' => '2016-01-02',
    'Mary' => 2,
    'John' => 4
  ),
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM