2017-04-11 150 views
2

我有消息表格式如下:从信息表中查询对话

+------------------------------------------------------------------+ 
| id|sender_id| recipient_id | message_text |created_at   | 
+------------------------------------------------------------------+ 
| 1 | 2  | 10   | "test1"  |"2017-04-10 09:05:45" | 
| 2 | 10  | 2   | "test2"  |"2017-04-10 09:05:47" | 
| 3 | 2  | 4   | "test3"  |"2017-04-10 09:05:49" | 
| 4 | 10  | 4   | "test4"  |"2017-04-10 09:05:51" | 
| 5 | 4  | 2   | "test5"  |"2017-04-10 09:05:53" | 
| 6 | 2  | 10   | "test6"  |"2017-04-10 09:05:58" | 
+------------------------------------------------------------------+ 

我想要做的就是让所有的“对话”一登录的用户(比如ID为2的用户) ,以及该对话的最后消息。 我设法拔出用户用户2的ID的拥有与使用此查询消息:

select distinct users.id 
from messages, users where 
(recipient_id = 2 and users.id = sender_id) 
or 
(sender_id = 2 and users.id = recipient_id); 

这是什么产生是

4 
10 

为用户2已经无论是从这两个人发送和/或接收的消息(test1, test2, test6对于10test3, test5对于4)。

我不能做的就是修改这个查询,从而也产生了由产生的ID发送或接收的最后一条消息 - 例如

4 | test5 
10 | test6 

回答

3

如果我正确理解您的要求,您希望获取涉及某个用户的每个对话的最新消息日期。在这种情况下,我们可以聚合某个给定用户的会话并保留最近的消息日期。

SELECT m1.* 
FROM messages m1 
INNER JOIN 
(
    SELECT LEAST(sender_id, recipient_id) AS first, 
      GREATEST(sender_id, recipient_id) AS second, 
      MAX(created_at) AS recent_date 
    FROM messages 
    WHERE sender_id = 2 OR recipient_id = 2 
    GROUP BY LEAST(sender_id, recipient_id), 
      GREATEST(sender_id, recipient_id) 
) m2 
    ON LEAST(m1.sender_id, m1.recipient_id) = m2.first AND 
     GREATEST(m1.sender_id, m1.recipient_id) = m2.second AND 
     m1.created_at = m2.recent_date 

输出:

enter image description here

说明:

在此查询的挑战是要找到一种方法,两个用户之间共同群组对话。我使用了LEAST/GREATEST技巧,这是我们可以将2 -> 44 -> 2对话视为逻辑上相同的一种方式。然后,使用GROUP BY,我们可以确定该对通话用户的最近对话日期。因此,在我上面的答案中的子查询发现,对于每一对用户,不考虑任何顺序,以及它最近的对话日期。然后,我们将此结果返回到messages表中,以引入实际的最新消息文本。

演示在这里:

Rextester

+0

这确实给了我几乎所需的结果,但我需要最近的消息而不是他们的日期。如果我只是添加消息文本进行选择,那么您使用日期所做的部分仍然正确,但我收到的消息与日期不匹配。我喜欢这个方法,你能不能解释一下你是如何得到这个解决方案的? – hpdobrica

+0

修改后的查询就像一个魅力!我真的很想听听你在那里做了些什么,我不想只是复制/粘贴它哈哈:) – hpdobrica

+0

@hpdobrica我给了你一个更深的解释。 –

0

使用在查询结束到order_by created_at desc声明获取最近的消息。

+1

这将不会得到预期的结果,因为你的做法会离开我们只是一个记录。 –

+0

'选择不同users.id,从消息messages.message_text ,用户 其中 (recipient_id = 2和users.id = SENDER_ID) 或 (SENDER_ID = 2和users.id = recipient_id)由messages.created_at降序顺序;' 这给我所有的消息从/从用户2从最新到最旧排序。另外当我添加message_text选择,我不再只获得2条记录,但所有的消息,这也是问题的一部分。 – hpdobrica