I have this kind of table for simple chat:
messages table structure
+----+---------+-----------+---------+------+------+
| id | to_user | from_user | message | read | sent |
+----+---------+-----------+---------+------+------+
And i need to get list of each conversation which looks like that
Username ---- Message ---- Date
I am using this query to do it:
SELECT *
FROM `messages`
WHERE `sent`
IN (
SELECT MAX( `sent` )
FROM `messages`
WHERE `from_user` = '1' --id of user who is requesting the list
OR `to_user` = '1' --id of user who is requesting the list
GROUP BY `to_user` , `from_user`
)
LIMIT 0 , 30
And this works almost fine, my problem is that it returns me not the last message of that conversation but last message from each user so let's say user 1
and 2
is talking and i'm getting this list, this is what i get:
+----+---------+-----------+-----------------------+------+---------------------+
| id | to_user | from_user | message | read | sent |
+----+---------+-----------+-----------------------+------+---------------------+
| 3 | 2 | 1 | Message 1 from user 1 | 0 | 2012-01-11 13:20:54 |
| 4 | 1 | 2 | Message 1 from user 2 | 0 | 2012-01-11 13:24:59 |
+----+---------+-----------+-----------------------+------+---------------------+
And i would like to get only last message which is 4 , cause sent
field is the highest in 4th record so how can i solve it?
EDIT After deleting group by
i'm getting only one message even if user was talking with more than one user
SELECT *
FROM `messages`
WHERE `sent`
IN (
SELECT MAX( `sent` )
FROM `messages`
WHERE (`from_user` = '1' OR `to_user` = '1')
)
LIMIT 0 , 30
the groupby is going to conbine them i believe.
You are getting the last message from each user because you have done GROUP BY for both: to_user and from_user.
There is no need to use GROUP BY clause in your query.
Here's how you do it:
SELECT *
FROM (SELECT *
FROM messages
WHERE from_user = ?
OR to_user = ?
ORDER by from_user, to_user, sent DESC
) x
GROUP BY from_user, to_user
ORDER BY sent DESC
LIMIT 1;
In mysql, a group by without aggregating the other columns returns the first row for each group. By selecting form an ordered row set (the inner query) we get the most recent row for each conversation.
Remove the group by
clause in your in
statement--it's useless in this case. It's returning a sent
timestamp for each distinct pairing of to_user
and from_user
. You really just want the max sent
where to_user
or from_user
equal some value. Lose the group by
, and you'll return exactly one record showing the latest message either to or from a user.
It looks like this:
SELECT *
FROM `messages`
WHERE `sent`
IN (
SELECT MAX( `sent` )
FROM `messages`
WHERE `from_user` = '1' --id of user who is requesting the list
OR `to_user` = '1' --id of user who is requesting the list
)
LIMIT 0 , 30
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.