mysql - 根据 USER 和 MESSAGE 表从 MySQL 数据库获取消息线程

标签 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; “接收者”另一个用户 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/

相关文章:

mysql - Rails 控制台 : User will not save - Stack level too deep

mysql - MySQL复制实际上如何工作? (关于线程)

php - 将文件作为 Blob 插入后出现错误文件类型 - PHP MySQL

php - 用来自 mysql 的数据填充 HTML 表格给出空表格单元格

mysql - 如何控制自增id?

mysql - 由于选择性低(所有 NULL),MariaDB 不在 1 列自连接上使用索引

MYSQL 语法 - 带条件的 GROUP BY

mysql - MySQL 中的 log-queries-not-using-indexes 和 LIKE

php - 将 CSV 文件直接导入 MySQL 数据库

php - mysql删除了文本的字符编码