对应的最后一条消息

时间:2014-08-01 21:04:48

标签: mysql sql

我有以下消息表(sid =发送通讯员ID,摆脱=接收通讯员ID,mdate =消息日期,mtext =消息文本),表示各方之间的通信:

sid|rid|    mdate   |  mtext
---+---+------------+----------
 1 | 2 | 01-08-2014 | message1    <-- 1st m. in corresp. between id=1 and id=2
 2 | 1 | 02-08-2014 | message2    <-- 2nd m. in corresp. between id=1 and id=2
 1 | 2 | 04-08-2014 | message3    <-- last m. in corrensp. between id=1 and id=2
 2 | 3 | 02-08-2014 | message4    <-- not id=1 correspondence at all
 1 | 3 | 03-08-2014 | message5    <-- 1st m. in corrensp. between id=1 and id=3
 3 | 1 | 04-08-2014 | message6    <-- 2nd m. in corrensp. between id=1 and id=3
 3 | 1 | 05-08-2014 | message7    <-- last m. in corrensp. between id=1 and id=3
 5 | 1 | 03-08-2014 | message8    <-- last m. in corrensp. between id=1 and id=5

请求MySQL查询应该返回一个通讯员(发送者或接收者)仅与最后一条消息(发送或接收)与其他方的通信。因此,从上一个消息表中,此id = 1对应的查询应该返回最后的通信消息(最后发送或接收):

sid|rid|    mdate   |  mtext
---+---+------------+----------
 1 | 2 | 04-08-2014 | message3
 3 | 1 | 05-08-2014 | message7
 5 | 1 | 03-08-2014 | message8

如何对MySQL进行此类查询?

3 个答案:

答案 0 :(得分:3)

假设两个通讯员之间没有完全相同时间戳的邮件,您可以使用过滤联接:

select  *
from    messages m
join    (
        select  case when sid > rid then sid else rid end r1
        ,       case when sid <= rid then sid else rid end r2
        ,       max(mdate) as max_mdate
        from    messages
        where   1 in (sid, rid)
        group by
                r1
        ,       r2
        ) as filter
on      m.sid in (filter.r1, filter.r2)
        and m.rid in (filter.r1, filter.r2)
        and m.mdate = filter.max_mdate

Example on SQL Fiddle.

答案 1 :(得分:3)

按sid分组如果rid = 1或者如果sid = 1则删除以找到最大日期,然后加入:

select a.*
from messages a
join (
  select if(sid=1, rid, sid) id, max(mdate) d
  from messages
  where sid = 1 or rid = 1
  group by id) b on ((a.sid=1 and a.rid=b.id) or (a.sid=b.id and a.rid=1)) and a.mdate = b.d;

demo

答案 2 :(得分:0)

以下联接是否适合您:

SELECT m.*  
FROM messages m
INNER JOIN
(SELECT
    MAX(
        CASE
            WHEN sid = 1 THEN mdate
            ELSE NULL
        END
    ) max_sdate,
    MAX(
        CASE
            WHEN rid = 1 THEN mdate
            ELSE NULL
        END
    ) max_rdate
FROM messages
WHERE sid = 1 or rid = 1
) max_dates
ON (m.sid = 1 AND mdate = max_dates.max_sdate) OR (m.rid = 1 AND mdate = max_dates.max_rdate);

SQL Fiddle demo