我需要在用户之间使用简单的内部消息系统.
我的桌子:
+--------------+ +---------------------+
| messages | | users |
+----+---------+ +---------------------+
| id | message | | id | username | ...
+----+---------+ +---------------------+
+------------------------------------------------------------------------------+
| users_messages |
+------------------------------------------------------------------------------+
| id | from_usr_id | to_usr_id | msg_id | thread_id | read | sent_at | read_at |
+------------------------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
INT 'thread_id' 表示对话线程,用于对消息进行分组.
BOOLEAN 'read' 表示用户是否打开/查看了消息.
我想按消息分组'thread_id',按顺序排列,'sent_at'我可以通过线程向用户显示他的最新消息.我还要计算每个线程中的消息.
我想为特定的用户ID获取类似的内容:
+----------------------------------------------------------------------------
| last_messages_by_conversation
+----------------------------------------------------------------------------
| message | from_username | sent_at | count_thread_msgs | count_unread_msg |
+----------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
TEXT 'message' 是具体的最新消息 'thread_id'
VARCHAR 'from_username'并DATETIME 'sent_at'与最新消息有关.
INT 'count_thread_msgs'并且INT 'count_unread_msg'与线程相关,表示线程中的消息总数和未读消息数.
每行代表一个线程/对话(分组依据'thread_id'),显示该'sent_at'特定线程的最后一条消息(按排序).
您正在寻找groupwise最大值,可以通过首先对users_messages表进行分组thread_id并选择MAX(sent_at),然后将结果重新连接到users_messages表上以查找该最大记录的其他字段来找到.
我发现这NATURAL JOIN是一个非常方便的捷径:
SELECT messages.message,
users.username AS from_username,
t.sent_at,
t.count_thread_msgs,
t.count_unread_msg
FROM users_messages NATURAL JOIN (
SELECT thread_id,
to_usr_id,
MAX(sent_at) AS sent_at,
COUNT(*) AS count_thread_msgs,
SUM(NOT read) AS count_unread_msg
FROM users_messages
WHERE to_usr_id = ?
GROUP BY thread_id
) t JOIN messages ON messages.id = users_messages.msg_id
JOIN users ON users.id = users_messages.from_usr_id
Run Code Online (Sandbox Code Playgroud)