2014-11-22 61 views
0

我在mysql中有一个表。其结构是:MySql按分组排序的SQL查询按

id sender receiver  time    message 
------------------------------------------------------- 
1  23   34  2014-11-02 14:55:02  1 
2  22   34  2014-11-02 16:55:02  2 
3  21   35  2014-11-02 16:55:02  5 
4  23   34  2014-11-02 16:55:02  2 
5  22   35  2014-11-02 16:55:02  1 

现在我需要做一个查询,如果通信超过one.Otherwise给它单列,将来自特定发件人请求一个接收器的最新消息。在这里,我想用接收器id = 34进行查询,它应该给我第4行和第2行。即

2  22   34  2014-11-02 16:55:02  2 
4  23   34  2014-11-02 16:55:02  2 

这里我不问从数据库的特定行数。这是一个对话db。我想要一个用户的对话列表。当同一个发送者和接收者有多行时,我想要最新的对话。

如何做到这一点?

回答

1

可以使用组通过获得最新消息的时间,然后用它在子查询来获取所有消息详情

Select * from 
table1 T 
Join(
     Select sender ,max(time) as lastTime 
     From table1 
     Where receiver = 34 
    Group by sender) T2 
On T.sender = T2.sender 
and T.time = T2.lastTime 
And T.receiver = 34 
+1

两件事情:您的最后一次,你说'T1.lastTime'线一个错字,你需要包括'WHERE接收器= 34'在外部查询也要不然一个可以返回额外的行。否则,它的作品。 [小提琴](http://sqlfiddle.com/#!2/543b8/3) – AdamMc331 2014-11-22 19:57:49

+1

@ McAdam331,谢谢更正。 – radar 2014-11-22 20:08:01

+0

发生了什么事情,第5行也被返回,因为它连接了sender = 22和匹配时间,这就是我如何捕获接收器错误。 – AdamMc331 2014-11-22 20:11:22

1

有很多方法来实现这一目标,一个方法是使用与连接左连接,然后条件组的数据,最后附加条件用于进一步过滤

select 
m.* from messages m 
left join messages m1 on m1.receiver = m.receiver 
and m.id < m1.id 
and m.sender = m1.sender 
where m1.id is null 
and m.receiver = 34; 

其它方法是使用exists作为替代为group by

select m.* from messages m 
where not exists 
(
    select 1 from messages m1 
    where 
    m1.receiver = m.receiver 
    and m.id < m1.id 
    and m.sender = m1.sender 
) 
and m.receiver = 34; 

demo