在与每个其他用户的每次对话中查询最新消息

Sae*_*eid 5 mysql sql

我有一个messages用户之间的对话表。表列的名称是:

messageID | fromUser | forUser | message | submitDate | seen
Run Code Online (Sandbox Code Playgroud)

样本数据:

1  |  1 | 2 | "hi"             | "12341" | 0
2  |  2 | 1 | "hi"             | "12342" | 0
3  |  1 | 3 | "hi"             | "12343" | 0
4  |  1 | 4 | "hi 4"           | "12344" | 0
5  |  2 | 1 | "hello"          | "12345" | 0
6  |  1 | 2 | "hello how r u?" | "12346" | 0
7  |  3 | 1 | "hello user 1"   | "12345" | 0
Run Code Online (Sandbox Code Playgroud)

我如何编写查询以查找我自己和系统中的每个其他用户之间发送的最后一条消息?我的意思是最后的消息是:

between user 1 and 2 : "hello how r u?"
between user 1 and 3 : "hello user 1"
between user 4 and 1 : "hi 4""
Run Code Online (Sandbox Code Playgroud)

我的查询:

$query = "SELECT DISTINCT `fromUser`, `forUser`, `message`, `seen`, 
                          `username`, `userPhoto` 
          FROM `messages`,`user` 
          WHERE (`forUser`= '$myUserID' OR `fromUser`= '$myUserID')
                AND (((`forUser`= `userID`) AND (`forUser` !=  '$myUserID')) 
                   OR ((`fromUser`= `userID`) 
                   AND (`fromUser` !=  '$myUserID'))) 
          ORDER BY `submitDate` DESC";
Run Code Online (Sandbox Code Playgroud)

但是这个查询需要获取对话中的所有消息!我只需要最后一条消息。

Joh*_*ger 2

如果messageIdauto_increment主键,那么您可以使用它的值来区分每个对话中的最新消息。如果submitDate有类型DATETIMETIMESTAMP那么将是用于该目的的另一种选择,但如果它有类型DATE则其分辨率是不够的。

不过,关键是识别和过滤最新消息的时间戳或 ID。您可以使用合适的聚合(子)查询来识别每个会话的 ID 或时间戳,并通过内部联接执行过滤,如下所示:

SELECT m.*
FROM
  messages m
  JOIN (
    SELECT
      MAX(messageId),
      CASE
        WHEN fromUser = '$myUserId' THEN forUser
        WHEN forUser = '$myUserId' THEN fromUser
      END AS otherUser  
    FROM messages
    GROUP BY
      CASE
        WHEN fromUser = '$myUserId' THEN forUser
        WHEN forUser = '$myUserId' THEN fromUser
      END
    HAVING otherUser IS NOT NULL
  ) other
    ON m.messageId = other.messageId
Run Code Online (Sandbox Code Playgroud)