在Postgresql中获取两个用户之间的对话中的最新消息

时间:2018-09-25 02:12:10

标签: sql postgresql group-by

我正在编写一个消息传递系统,并试图在给定用户(id = 46)的每次对话中查找最新消息。这是我目前拥有的:

<C-;>

哪个输出:

SELECT sender, receiver, MAX(created_at) maxDate 
FROM message 
WHERE sender = 46 OR receiver = 46 
GROUP BY sender, receiver; 

问题在于,45和46之间的对话是一次对话,但是由于每个人彼此发送消息,因此结果中有两行。

我只想从整个对话中获取最新消息,所以我将以某种方式修改SQL以获取以下内容:

45  46  2018-09-24 21:14:47
46  45  2018-09-24 21:10:32
46  1   2018-09-24 21:08:47
46  25  2018-09-23 22:25:09

另一行被删除,因为在他们的对话中45发送了最新消息。

我一直对此感到很头疼,似乎无法弄清。

2 个答案:

答案 0 :(得分:1)

这是一种方法:

SELECT m.*
FROM message m 
WHERE 46 IN (m.sender, m.receiver) AND
      (LEAST(m.sender, m.receiver), GREATEST(m.sender, m.receiver), created_at) IN 
       (SELECT LEAST(m2.sender, m2.receiver), GREATEST(m2.sender, m2.receiver), MAX(m2.created_at)
        FROM message m2
        GROUP BY LEAST(m2.sender, m2.receiver), GREATEST(m2.sender, m2.receiver)
       );

Here是一个逻辑的说明。

答案 1 :(得分:1)

我认为最快的方法是

SELECT GREATEST(sender, receiver), LEAST(sender, receiver), MAX(created_at) AS maxdate
FROM t
WHERE sender = 46
  OR receiver = 46 
GROUP BY GREATEST(sender, receiver), LEAST(sender, receiver);

或者您可以尝试使用DISTINCT ON

SELECT DISTINCT ON(GREATEST(sender, receiver), LEAST(sender, receiver)) GREATEST(sender, receiver), LEAST(sender, receiver),  created_at AS maxdate
FROM t
WHERE sender = 46
  OR receiver = 46 
ORDER BY GREATEST(sender, receiver), LEAST(sender, receiver), created_at DESC;