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

How to get all latest messages but with limit to one for every user message

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

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

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

所以基本上我需要 select 所有 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

我正在使用 MySQL 和 PHP。

一种方法使用 window 函数:

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)