我正在尝试查找用户 ID 1
与之进行过对话的人员(如交换消息)。我只需要每个其他用户的 id 一次,但我想获取按日期(或最高 ID,因为 id 是增量键)排序的结果 id,其中每个用户与用户的最新对话(消息) 1
发生了。用户1
可能是发送消息的人,也可能是接收消息的人,任何情况都算作与其他用户的“对话”或交互。
这就是我正在做的事情
SELECT fromId AS userId FROM messaging
WHERE toId = 1
UNION
SELECT toId AS userId FROM messaging
WHERE fromId = 1
但是,当然,这只返回每个用户的 id,但不会按照消息发生的顺序返回结果。例如,如果用户与用户 id 5 进行了对话,并且该消息的 id 高于他与用户 6 进行的对话,则顺序必须为 5, 6
有什么方法可以只用一个查询来做到这一点吗?
谢谢。
最佳答案
你已经相当接近了,只需要向日期联合添加一个额外的字段,然后按 id 分组,并按最大时间排序。像这样:
select id, max(message_time)
from
(select fromid id, message_time
from messaging
where toid = 1
union
select toid id, message_time
from messaging
where fromid = 1
) q
group by id
order by max(message_time) desc;
这是一个适合您的 fiddle 示例:http://sqlfiddle.com/#!9/d248e/2
根据评论请求进行编辑
此查询将获取每个对话的最新消息以及消息文本。
select t1.id, t1.message_time, t1.message
from
(select fromid id, message_time, message
from messaging
where toid = 1
union
select toid id, message_time, message
from messaging
where fromid = 1
) t1
left join
(select fromid id, message_time, message
from messaging
where toid = 1
union
select toid id, message_time, message
from messaging
where fromid = 1
) t2
on t1.id = t2.id and t1.message_time < t2.message_time
where t2.id is null
order by t1.message_time desc;
该查询的总体要点与之前的查询相同 - 构建一个派生表,其中仅包含用户 ID、消息日期,这次还包含消息。在用户 ID 上将该派生表左连接到自身(因此重复联合查询),而且在消息时间较长的情况下也是如此。因为我们是左连接,如果没有具有相同用户 ID 但时间戳更大的消息,则结果的后半部分会留下空值。这表明我们有最新的消息时间以及文本。剩下要做的就是根据这些空值进行过滤并排序。
关于mysql - 如何仅选择最近(和多个)值一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29586083/