MySQL Query with the count, group by

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



MySQL Query with the count, group by



Table: statistics


id | user | Message
----------------------
1 | user1 |message1
2 | user2 |message2
3 | user1 |message3



I am able to find the count of messages sent by each user using this query.


select user, count(*) from statistics group by user;



How to show message column data along with the count? For example


user | count | message
------------------------
user1| 2 |message1
|message3
user2| 1 |message2





what is size of message column?
– Shubham
Aug 10 at 11:29





message varchar(100)
– lazyboy
Aug 10 at 11:30





Is your sample data and expect result correct? because message3 is for user1.
– D-Shih
Aug 10 at 11:37



message3


user1





What's your mysql version?
– D-Shih
Aug 10 at 11:42





@D-Shih mysql version is 5.6 and yes sample data is correct. This is messages sent by the user. user1 has sent 2 messages: message1 and message3.
– lazyboy
Aug 10 at 12:14




5 Answers
5



You seem to want to show Count by user, which message sent by user.


Count


user


message


user



If your mysql version didn't support window functions, you can do subquery to make row_number in select subquery, then only display rn=1 users and count


row_number


rn=1


CREATE TABLE T(
id INT,
user VARCHAR(50),
Message VARCHAR(100)
);


INSERT INTO T VALUES(1,'user1' ,'message1');
INSERT INTO T VALUES(2,'user2' ,'message2');
INSERT INTO T VALUES(3,'user1' ,'message3');



Query 1:


SELECT (case when rn = 1 then user else '' end) 'users',
(case when rn = 1 then cnt else '' end) 'count',
message
FROM (
select
t1.user,
t2.cnt,
t1.message,
(SELECT COUNT(*) from t tt WHERE tt.user = t1.user and t1.id >= tt.id) rn
from T t1
join (
select user, count(*) cnt
from T
group by user
) t2 on t1.user = t2.user
) t1
order by user,message



Results:


| users | count | message |
|-------|-------|----------|
| user1 | 2 | message1 |
| | | message3 |
| user2 | 1 | message2 |


select user, count(*) as 'total' , group_concat(message) from statistics group by user;



You could join the result of your group by with the full table (or vice versa)?


join


group by



Or, depending on what you want, you could use group_concat() using n as separator.


group_concat()


n





can you explain how join will work in this case, if user is not to be repeated
– Shubham
Aug 10 at 11:47






@Shubham See D-Shih's new answer for an example.
– Danny_ds
Aug 10 at 12:06



Use Group_concat


select user, count(0) as ct,group_concat(Message) from statistics group by user;



This will give you message in csv format



NOTE: GROUP_CONCAT has size limit of 1024 characters by default in mysql.



For UTF it goes to 1024/3 and utfmb4 255(1024/4).



You can use group_concat_max_len global variable to set its max length as per need but take into account memory considerations on production environment


SET group_concat_max_len=100000000



Update:



You can use any separator in group_concat


Group_concat(Message SEPARATOR '----')





Would it be possible to get output in next row instead of csv since "message" column is already having "comma" and it is difficult to parse by group_concat's "comma".
– lazyboy
Aug 10 at 11:41





check update @lazyboy
– Shubham
Aug 10 at 11:43



Try grouping with self-join:


select s1.user, s2.cnt, s1.message
from statistics s1
join (
select user, count(*) cnt
from statistics
group by user
) s2 on s1.user = s2.user






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

Creating a leaderboard in HTML/JS