MySQL,如何从消息列表中选择对话

时间:2016-01-10 21:51:08

标签: mysql sql mysqli

我有这段代码:

SELECT a.id, a.to_id, a.from_id, a.seen, a.date, a.message

FROM  `Chat_messages` a

INNER JOIN (
    SELECT MAX(  `id` ) AS id
    FROM  `Chat_messages` AS  `alt` 
    WHERE  `alt`.`to_id` =7
    OR  `alt`.`from_id` =7
    GROUP BY  `to_id` ,  `from_id`
)b ON a.id = b.id

返回:

enter image description here

所以,我希望得到用户的对话(发送和接收的消息)及其最新消息。 最新消息正常,但问题是我从收到的消息中获得了2行(#1和#2)和从发送的消息中获得2行(#3和#4),但我只需要2个结果,因为有2个会话。

任何帮助将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:3)

选择保存最新发送消息的行和分别保存最新接收消息的行的最佳方法是使用row_number()窗口函数。不幸的是,MySql不支持窗口函数,所以我认为最好使用两个嵌套的SELECT:

SELECT z.id, max(z.to_id), max(z.from_id), max(z.seen), max(z.date), max(z.message)
FROM chat_messages z
LEFT JOIN 
(SELECT x.from_id, max(date) date
FROM chat_messages x
GROUP BY x.from_id) f
ON z.from_id = f.from_id AND z.date = f.date
LEFT JOIN
(SELECT y.to_id, max(date) date
FROM chat_messages y
GROUP BY y.to_id) t
ON z.to_id = t.to_id AND z.date = t.date
GROUP BY z.id

如果您长期关注正确性,我建议不要在ID上使用max。

答案 1 :(得分:2)

您可以group by least(to_id, from_id), greatest(to_id, from_id)确保两个人之间的转化合并:

SELECT a.id, a.to_id, a.from_id, a.seen, a.date, a.message

FROM  `Chat_messages` a

INNER JOIN (
    SELECT MAX(  `id` ) AS id
    FROM  `Chat_messages` AS  `alt` 
    WHERE  `alt`.`to_id` =7
    OR  `alt`.`from_id` =7
    GROUP BY  least(`to_id` ,  `from_id`), greatest(`to_id` ,  `from_id`)
)b ON a.id = b.id