获得了两个版本的查询。也不是我需要的......
尝试返回所有用户,以及 向该用户发送<或>
最后,需要订购整个结果集,让这些用户先“等待响应”,然后按最新消息的时间进行排序。
版本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
版本1的问题:'_message_sent_time'是正确的(通过MAX),但'_message_awaiting_response'标志始终是从MAX()发生之前联接中首先出现的任何消息派生出来的,这可能不是最多的最近的消息。
第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
对于版本2,问题基本相同 - 由于没有MAX()聚合函数,连接中找到的第一条消息(不是最新的)被DISTINCT单挑出来。
是否有一种简单的方法可以确保最新消息在此处定位?
P.S。它需要在MySQL 4中工作;)
答案 0 :(得分:2)
最简单的方法应该是:
SELECT * FROM
(SELECT `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`
ORDER BY `users`.`id`, `messages`.`time_sent` DESC
) V
GROUP BY V.`id`
ORDER BY `_message_awaiting_response` DESC, `_message_time_sent` DESC
但是,应该强调的是,虽然这可能将起作用,但保证无法正常工作 - 未分类,分组选择语句中包含的未分组值通常是那些首先是顺序,但MySQL文档并未将此行为描述为可靠。
应始终有效的替代方案(假设给定用户没有多条具有相同时间戳的消息)将是:
select u.*,
m.`time_sent` AS `_message_time_sent`,
(m.`user_id` = u.`id`) AS `_message_awaiting_response`
from `users` u
left join (select `user_id`, max(`time_sent`) AS `last_sent`
from (select `time_sent`, `user_id` from `messages` union all
select `time_sent`, `to_user_id` `user_id` from `messages`) v
group by `user_id`) lm
on u.`user_id` = lm.`user_id`
left join `messages` m
ON m.`time_sent` = lm.`last_sent` and
lm.`user_id` in (m.`user_id`, m.`to_user_id`)
ORDER BY `_message_awaiting_response` DESC, `_message_time_sent` DESC