我可能会要求我的 SQL 查询一次完成一些操作。我正在编写一个消息传递脚本,并希望显示对话线程的摘要列表,就像手机上的短信一样;所以消息线程的发送者、最后一条消息的日期/时间以及每个用户未读消息的数量。
所以考虑这个查询,假设我们要检查的用户 ID 是 1:
SELECT u.id,
u.name,
u.image,
m.message,
m.sender,
m.sent,
sum(if(m.sender<>1,m.unread,0)) as unread
FROM messages m
INNER JOIN members u ON u.id = m.sender OR u.id = m.receiver
WHERE (m.sender = 1 OR m.receiver = 1) AND u.id <> 1
GROUP BY IF(m.sender = 1, m.receiver, m.sender)
ORDER BY m.sent DESC
在此,字段类型应该相当明显。 'sender' 是发送消息的人的 ID; “接收者”另一个用户 ID; “发送”消息发送的日期/时间;和“未读”tinyint 标志,该标志为 0 或 1。
在大多数情况下,这都是有效的 - 它给了我一个独特的对话线程列表以及正确的未读消息数量,但是,它作为最后发送的消息而拾取的消息似乎总是第一个,而不是最后一个就好像 ORDER BY m.sent DESC 被 GROUP 或 JOIN 覆盖一样。我显然在做一些愚蠢的事情,但我就是看不到。有什么指点吗?
最佳答案
好吧,经过多次尝试和错误后,我通过向消息表添加另一个联接来解决这个问题,该联接只是获取每个分组对话的最后一个唯一消息 ID,即:
SELECT u.id,
u.name,
u.image,
m.message,
m.sender,
m.sent,
sum(if(m.sender<>1,m.unread,0)) as unread
FROM messages m
INNER JOIN members u ON u.id = m.sender OR u.id = m.receiver
JOIN (SELECT max(id) id FROM messages GROUP BY IF(sender=1, receiver, sender)) t ON m.id = t.id
WHERE (m.sender = 1 OR m.receiver = 1) AND u.id <> 1
GROUP BY IF(m.sender = 1, m.receiver, m.sender)
ORDER BY m.sent DESC
我仍然有点困惑为什么原始查询没有按照发送的 ORDER BY 获取最后一条消息,但是嘿 - 修复就是修复。
关于mysql - 根据 USER 和 MESSAGE 表从 MySQL 数据库获取消息线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47283753/