如何获取所有最新消息,但每条用户消息限制为一条

Posted

技术标签:

【中文标题】如何获取所有最新消息,但每条用户消息限制为一条【英文标题】:How to get all latest messages but with limit to one for every user message 【发布时间】:2021-06-15 10:24:07 【问题描述】:

我已经搜索了很多,但可能我不知道如何正确地提出问题。

我将所有用户之间的所有聊天消息存储在名为 'user_messages' 的表中,如下所示:

message_from_user_id | message_to_user_id | message_content | message_date
                   1 |                  2 | "hey"           |       07:36
                   1 |                  2 | "how are u?"    |       07:37
                   2 |                  1 | "hey, im fine"  |       07:38
                   3 |                  1 | "wassup"        |       09:21
                   4 |                  2 | "wow"           |       11:55
                   5 |                  1 | "example"       |        5:34

现在假设我是 id 为 1 的用户。我想显示我与所有人的最新聊天记录(类似于 messenger)。

我想要达到的结果是:

message_from_user_id | message_to_user_id | message_content | message_date
                   3 |                  1 | "wassup"        |       09:21
                   2 |                  1 | "hey, im fine"  |       07:38
                   5 |                  1 | "example"       |        5:34

所以基本上我需要选择message_from_user_id = 1message_to_user_id = 1 的所有消息,但我怎样才能让每个聊天的唯一一个最新结果显示?

即使在这种情况下:

message_from_user_id | message_to_user_id | message_content | message_date
                   1 |                  2 | "hey"           |       07:36
                   1 |                  2 | "how are u?"    |       07:37
                   2 |                  1 | "hey, im fine"  |       07:38

我只想得到一个结果:

               2 |                  1 | "hey, im fine"  |       07:38

我正在使用 mysqlphp

【问题讨论】:

你使用什么 MySQL 版本? 这是 mariadb 10.5 【参考方案1】:

一种方法使用窗口函数:

select um.*
from (select um.*,
             row_number() over (partition by  coalesce(nullif(message_from_user_id, 1), message_to_user_id)
                                order by message_date desc
                               ) as seqnum
      from user_messages um
      where 1 in (message_from_user_id, message_to_user_id)
     ) um
where seqnum = 1;

表达式:

coalesce(nullif(message_from_user_id, 1), message_to_user_id)

只是一种更简洁的写法:

(case when message_from_user_id <> 1
      then message_to_user_id
      else message_from_user_id
 end)

【讨论】:

以上是关于如何获取所有最新消息,但每条用户消息限制为一条的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 dhooks 查找频道中发送的最新消息

MYSQL在一个语句中多对多选择(聊天,最新消息,用户名)

如何使用 smack 和 openfire 获取 IOS 中每个聊天会话的最后一条消息?

仅使用 jQuery (Ajax) 和 PHP 从 MySQL 获取最新消息? (在线聊天APP)

Python/imaplib - 如何获取消息的标签?

MySQL13分组查询取每组最新的一条数据