从基于USER和MESSAGE表的MySQL数据库获取消息线程

时间:2017-11-14 10:48:32

标签: mysql

我可能会问我的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; 'receiver'是另一个用户ID; '发送'消息发送的日期/时间;并且'未读'一个0或1的tinyint标志。

在大多数情况下这是有效的 - 它给了我一个独特的会话线程列表加上正确数量的未读消息,但是,它发送的最后一个消息的消息似乎总是第一个,而不是最后一个一个好像ORDER BY m.sent DESC被GROUP或JOIN覆盖。我显然做了一些蠢事,但我看不到它。有什么指针吗?

1 个答案:

答案 0 :(得分:0)

好的,我设法通过在message表中添加另一个连接来经过多次试验和错误后解决了这个问题,该表只是为每个分组的对话抓取了最后一个唯一的消息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接收最后一条消息,但是嘿 - 修复是一个修复。