我有一个sql表,其中包含用户之间的对话。我需要从每次对话中检索最后一条信息以便预览。
id | sender | receiver | message | date
1 | 1 | 2 | Hello | 2015-12-08 20:00
2 | 2 | 1 | Hey | 2015-12-08 20:10
3 | 2 | 1 | You there? | 2015-12-08 21:00
4 | 1 | 3 | Yes | 2015-12-08 21:15
5 | 4 | 1 | Hey buddy | 2015-12-08 22:00
我知道网站上有很多类似的问题,但我无法解决这个问题。
我试过这个代码,但不能正常工作:
SELECT *
FROM messages
WHERE receiver = '{$id}'
GROUP BY sender
ORDER BY id DESC
LIMIT 10;
只是为了定义什么是会话在你的表是一个痛苦,我想一个会话是所有的行
(发送方= @senderId,,receiver=@receiverId) || (sender=@receiverId &&接收机= @senderId)
按这个概念分组,我甚至不愿去想它
对我来说,你错过了一个概念,"对话"
如果你有一个像这样的表对话
ConversationId | Users1 | User2
和Message like
Id | ConversationId | UserSendingId | Message | Date
现在您可以按ConversationId分组,并采用最后一条消息,如
SELECT * <-- avoid * better use all row names
FROM Message
Where id in (
select max(id) from message group by ConversationId
)
会话表的表示只是一种快速的方法,当您希望每个会话有超过2个用户时,您可以使用从1到许多会话和会话用户的关系来做更好的解决方案,以避免修改会话表。
我认为如果您想为特定用户识别对话,您将需要选择他们是发送者或接收者的行。
然后从对话中获取最新消息,您可以按当前用户而不是的发送者/接收者中的任何一个分组,然后选择最大ID。
SELECT * FROM messages
WHERE id IN (
SELECT MAX(id) AS last_msg_id
FROM messages WHERE receiver = ? OR sender = ?
GROUP BY IF(sender = ?, receiver, sender)
)
我不认为这个查询会执行得很好。我同意另一个答案,如果会话在数据库中定义,那么查询会话将更容易。
示例:
SELECT x.*
FROM my_table x
JOIN
( SELECT LEAST(sender,receiver) user1
, GREATEST(sender,receiver) user2
, MAX(date) date
FROM my_table
GROUP
BY user1
, user2
) y
ON LEAST(sender,receiver) = user1
AND GREATEST(sender,receiver) = user2
AND y.date = x.date;
SELECT m.id, m.added_date, m.message, u.username, u.image, m.from_id, m.to_id
FROM tbp_registration AS u
LEFT JOIN tbp_chats AS m ON m.from_id = u.id
WHERE m.id IN (
SELECT MAX(id)
FROM tbp_chats
WHERE from_id = '$user_id' OR to_id = '$user_id'
GROUP BY LEAST(from_id, to_id), GREATEST(from_id, to_id)
)