我有一个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)
但是这个查询需要获取对话中的所有消息!我只需要最后一条消息。
如果messageId是auto_increment主键,那么您可以使用它的值来区分每个对话中的最新消息。如果submitDate有类型DATETIME或TIMESTAMP那么将是用于该目的的另一种选择,但如果它有类型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)
| 归档时间: |
|
| 查看次数: |
2472 次 |
| 最近记录: |