Got two versions of a query. Neither does quite what I need..
Trying to return all users, along with the time of the latest message sent either to OR from that user. An additional flag shows whether that last message was from the user in the current row (hence whether they’re ‘awaiting response’).
Finally, the entire result set needs to be ordered to have those users ‘awaiting response’ first, and secondarily ordered by the time of the latest message.
Version 1:
SELECT `users`.*,
MAX(`messages`.`time_sent`) AS `_message_time_sent`,
(`messages`.`user_id` = `users`.`id`) AS `_message_awaiting_response`
FROM `users` LEFT JOIN `messages`
ON (`messages`.`user_id` = `users`.`id` OR `messages`.`to_user_id` = `users`.`id`)
GROUP BY `users`.`id`
ORDER BY `_message_awaiting_response` DESC, `messages`.`time_sent` DESC
The problem with version 1: the ‘_message_sent_time’ is correct (via MAX), but the ‘_message_awaiting_response’ flag is always derived from whichever message appeared first in the join before the MAX() occurred, which may not be the most recent message.
Version 2:
SELECT DISTINCT `users`.*,
`messages`.`time_sent` AS `_message_time_sent`,
(`messages`.`user_id` = `users`.`id`) AS `_message_awaiting_response`
FROM `users` LEFT JOIN `messages`
ON (`messages`.`user_id` = `users`.`id` OR `messages`.`to_user_id` = `users`.`id`)
GROUP BY `users`.`id`
ORDER BY `_message_awaiting_response` DESC, `messages`.`time_sent` DESC
With version 2, the problem is largely the same – due to there being no MAX() aggregate function, the first message found in the join (not the most recent) is singled-out by DISTINCT.
Is there a simple way of making sure the latest message gets targeted here?
P.S. It needs to work in MySQL 4 😉
The simplest way to do this should be:
However, it should be stressed that although this probably will work, it cannot be guaranteed to work – unaggregated, ungrouped values included in a grouped select statement are normally those first in order, but MySQL documentation does not describe this behaviour as reliable.
An alternative that should always work (provided that a given user doesn’t have multiple messages with the same timestamp) would be: