简体   繁体   中英

MySQL Group by column, then count by another column

I have a challenging MySQL problem that is beyond my basic knowledge, I would really appreciate any help.

I currently have the following query:

select users.userid, CAST(posts.time AS DATE) 
FROM users INNER JOIN posts ON users.post_id = posts.id

Sample output:

userid | CAST(posts.time AS DATE)    
1............2015-01-05    
2............2015-02-06    
2............2015-04-07   
2............2015-04-07    
3............2015-04-07
1............2015-02-06    
7............2015-01-05

userid can repeat itself, there could be 10 different rows with userid = 1; same goes for the date column. I would like to count how many rows each userid had for each distinct date. Based on the above data, the output should be:

-----------------------1----------2--------3---------4--------5--------6-------7
2015-01-05.............1..........0........0.........0........0........0.......1
2015-02-06.............1..........1........0.........0........0........0.......0
2015-04-07.............0..........2........1.........0........0........0.......0

I have 7 users in total. I would like to further replace the user id with a name that I define; eg I would define 1 in the heading/title to be displayed as Mike, 2 to be displayed as George, and so forth...

Is it possible? Thanks everyone.

If you have 7 users only, and only ever will, pivoting the data is not too difficult:

select date(posts.time),
       count(case when userid = 1 then userid end) as `1`,
       count(case when userid = 2 then userid end) as `2`,
       count(case when userid = 3 then userid end) as `3`,
       count(case when userid = 4 then userid end) as `4`,
       count(case when userid = 5 then userid end) as `5`,
       count(case when userid = 6 then userid end) as `6`,
       count(case when userid = 7 then userid end) as `7`
users INNER JOIN posts ON users.post_id = posts.id
group by date(posts.time)

demo here

If your number of users is variable, or prone to change - it becomes annoying and you'd be better off looking to your application language to take care of it.

Here's what I have (I didn't complete it for you):

SELECT date, SUM(id_1) AS Mike, SUM(id_2) AS George FROM (SELECT CASE id WHEN 1 THEN 1 ELSE 0 END as id_1, CASE id WHEN 2 THEN 1 ELSE 0 END as id_2, date FROM test_dates) as tmp GROUP BY date;

+------------+------+--------+
| date       | Mike | George |
+------------+------+--------+
| 2015-01-05 |    1 |      0 |
| 2015-02-06 |    1 |      1 |
| 2015-04-07 |    0 |      2 |
+------------+------+--------+

The trick of substituting a summation of 1s when what you want is a count is a common reporting trick that is worth remembering. Blew my mind when I first saw it.

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