Reputation: 331
Suppose I have a table messages like this:
id sender receiver content created_at
1 100 101 Hi 2015-12-01
2 100 101 Hello 2015-12-02
3 100 101 World 2015-11-02
4 103 101 Like 2015-11-05
5 103 101 Do 2015-11-04
6 105 102 ..................
With the receiver specified, I want to get the latest message and number of messages from each user, i.e. for user 101, I want to get:
2 100 101 Hello 2015-12-02 3
4 103 101 Like 2015-11-05 2
Is it possible to do that with a single statement or what's the most elegant way ?
Upvotes: 0
Views: 56
Reputation: 33945
SELECT x.*
, y.total
FROM my_table x
JOIN
( SELECT receiver
, sender
, MAX(created_at) max_created_at
, COUNT(*) total
FROM my_table
GROUP
BY receiver
, sender
) y
ON y.receiver = x.receiver
AND y.sender = x.sender
AND y.max_created_at = x.created_at
-- [WHERE receiver = 101]
;
+----+--------+----------+---------+------------+-------+
| id | sender | receiver | content | created_at | total |
+----+--------+----------+---------+------------+-------+
| 2 | 100 | 101 | Hello | 2015-12-02 | 3 |
| 4 | 103 | 101 | Like | 2015-11-05 | 2 |
| 6 | 105 | 102 | Re | 2015-11-04 | 1 |
+----+--------+----------+---------+------------+-------+
http://www.sqlfiddle.com/#!9/3fef7/1
Upvotes: 0
Reputation: 4329
Idea here is to get latest record which can be acheived by ordering by created_at and then using group by to get the count.
SELECT a.id,a.sender,a.receiver,a.content,a.created_at,count(a.sender) from (Select * from messages order by created_at desc) a group by sender ;
Upvotes: 0
Reputation: 1269793
Aggregate the information for 101
in a subquery, and then join that back to the original table:
select m.*, mm.maxca
from messages m join
(select m2.receiver, max(m2.created_at) as maxca, count(*) as cnt
from messages m2
where m2.receiver = 101
) mm
on m.receiver = mm.receiver and m.created_at = mm.created_at
where m.receiver = 101 ;
Upvotes: 1