To get a list of all the conversations for a specific user, and the last message sent (and it's details) for each conversation, in a single query:
SELECT
convo.convoid,
message.pmid,
message.dateline,
CASE WHEN fromid = 4 then "SENT" ELSE "RECEIVED" as direction
FROM
(SELECT convoid, max(dateline) as maxdateline FROM table_messages GROUP BY convoid) convo
INNER JOIN table_messages message
ON convo.convoid = message.convoid AND
convo.maxdateline = message.dateline
WHERE
fromid = 4 or toid = 4
Here we are working with two sets again. The first (from the FROM
) is a list of all convoid's
and their max dateline
. Then we INNER JOIN
those with the same table on the relationship of convoid and dateline. This will give us a record set of every conversation and it's most recent message.
Then we restrict in the WHERE
clause to get just the conversations where either the fromid
or the toid
is the user you are interested in.
For the fun, I added the CASE
statement, just to bring in more information about that last message sent (whether it was sent by the user or received by the user).
It MIGHT be quicker to do:
SELECT
convo.convoid,
message.pmid,
message.dateline,
CASE WHEN fromid = 4 then "SENT" ELSE "RECEIVED" as direction
FROM
(SELECT convoid, max(dateline) as maxdateline FROM table_messages GROUP BY convoid WHERE fromid = 4 or toid = 4) convo
INNER JOIN table_messages message
ON convo.convoid = message.convoid AND
convo.maxdateline = message.dateline
Depending on how MySQL optimizes the first query. If it tries to get every conversation and then the last message, then restricts it for the user then you can force the optimizer to instead, with this version, only get conversations for the user, then get the latest message for those conversations. My bet though is that it's a wash and that MySQL will properly optimize the first query to do what is explicitly stated in the second. But... I figured just in case, I would put it here.
For readability sake, I like the first query better since one can very quickly see the conditions in the main query's WHERE
clause. Otherwise you have to hunt in the subquery.