MySql SELECT仅按时间戳排序来自不同线程的最新消息-Private消息收件箱类似于Facebook(2013)

时间:2013-02-24 06:02:07

标签: mysql distinct max private-messaging

尝试重新创建类似于Facebook目前设置的私人消息系统。有问题的部分是SELECT只有来自不同线程的最新消息按时间戳排序。

这是我到目前为止最接近的查询。问题是收件箱应该只为每个线程返回一行,目前我的查询从同一个线程返回多行:

SELECT m.created_on, m.thread_id, m.message_id, m.created_by, m.body, u.first_name, u.last_name, u.thumb_img

FROM pms_messages AS m, pms_recips AS r, users AS u

WHERE r.uid =19

AND r.status

IN ('A', 'N'
)

AND r.thread_id = m.thread_id

AND (SELECT max(r.message_id)) = m.message_id 

AND m.created_by = u.uid

ORDER BY created_on DESC

这是我当前数据库设置的img,如果它可以简化我的查询并完成工作,我可以对我的表进行更改。再往下是我的表格/收件箱规格的更详细说明。

enter image description here

更具体一点:

*任何两个用户之间的消息发生在一个正在进行的线程中。任何2个用户之间的所有消息只是一个正在进行的对话(线程)的延续即使两个用户之间都删除了所有先前的消息,任何未来的消息仍将在同一个线程上发生。

*个人消息由message_id跟踪。

*每个帖子在任何给定时间只在收件箱中显示一次,并显示该帖子中最新的信息。

*收件箱和收件箱中的收件箱和收件箱邮件将显示在同一个收件箱中。

因此,如果用户A和我有一条消息我还没有从用户B-20分钟前读过,我回复了一个msg用户C昨天发送给我 - 10分钟前来自用户D的另一条消息 - 2分钟前我的收件箱应如下所示:

使用USER D的线程 - 显示msg用户D发送给我。


使用USER C-的线程 - 显示我发送给用户C的消息


带有USER B的线程 - 显示msg用户B发给我的


*显示的线程将按最近的顺序排序 - 最旧的。

2 个答案:

答案 0 :(得分:1)

表格JOIN

pms_messages包含以下内容:

SELECT thread_id, MAX(Created_ON) AS NewestDate
FROM messages 
GROUP BY thread_id

然后它会删除所有消息,但最新的消息会有MAX(Created_ON)。像这样:

SELECT 
  m.created_on, 
  m.thread_id, 
  m.message_id, 
  m.created_by, 
  m.body, 
  u.first_name, 
  u.last_name, 
  u.thumb_img
FROM pms_messages AS m
INNER JOIN
(
   SELECT thread_id, MAX(Created_ON) AS NewestDate
   FROM messages 
   GROUP BY thread_id
) AS m2  ON m.created_on = m2.Newestdate
        AND m.thread_id  = m2.thread_id
INNER JOIN pms_recips AS r ON r.thread_id  = m.thread_id
INNER JOIN users      AS u ON m.created_by = u.uid
WHERE r.uid =19
  AND r.status IN ('A', 'N')
ORDER BY created_on DESC;

更新1

r.message_id = m.message_id添加到两个表JOINpms_messages之间的pms_recips条件。像这样:

SELECT 
  m.created_on, 
  m.thread_id, 
  m.message_id, 
  m.created_by, 
  m.body, 
  u.first_name, 
  u.last_name, 
  u.thumb_img
FROM pms_messages AS m
INNER JOIN
(
   SELECT thread_id, MAX(Created_ON) AS NewestDate
   FROM pms_messages
   GROUP BY thread_id
) AS m2  ON m.created_on = m2.Newestdate
        AND m.thread_id  = m2.thread_id
INNER JOIN pms_recips AS r  ON r.thread_id  = m.thread_id 
                           AND r.message_id = m.message_id
INNER JOIN users      AS u  ON m.created_by = u.uid
WHERE r.uid =19
  AND r.status IN ('A', 'N')
ORDER BY created_on DESC;

SQL Fiddle Demo

答案 1 :(得分:0)

    SELECT * FROM 
        (SELECT * FROM messages ORDER BY created_at DESC) messages
    GROUP BY IF(from_user_id < to_user_id, CONCAT_WS('_', from_user_id, to_user_id), CONCAT_WS('_', to_user_id, from_user_id));