如何只选择一次最近(和多个)值?

时间:2015-04-12 04:53:32

标签: mysql select union

我试图找到用户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

有没有办法只用一个查询来做到这一点?

感谢。

1 个答案:

答案 0 :(得分:0)

你相当接近,只需要为日期的联合添加一个额外的字段,然后按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;

以下是您的示例小提琴: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;

那个的一般要点与之前的查询相同 - 构建一个只有userid,message date和此消息的派生表。左派连接派生表到自己(因此重复联合查询)对用户ID,但也消息时间更长。因为我们没有加入,如果没有相同用户ID的消息,但是时间戳更大,我们在结果的后半部分留下空值。这表明我们有最新的消息时间以及文本。剩下要做的就是根据这些空值进行过滤,然后排序。

updated fiddle