我可能会问我的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覆盖。我显然做了一些蠢事,但我看不到它。有什么指针吗?
答案 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接收最后一条消息,但是嘿 - 修复是一个修复。