MySQL GROUP BY / ORDER BY问题与平面消息表/线程

时间:2011-06-24 18:29:10

标签: mysql sql group-by sql-order-by messaging

好的,我正在尝试基于此类似的东西,但不能完全固定它:GROUP BY and ORDER BY

基本上,希望查询在当前登录用户和任何其他用户之间的每个“线程”中查找最新消息,但是通过平面(非''''')消息表:

messages {
  id,
  from_uid,
  to_uid,
  message_text,
  time_added
}

假设当前用户的uid为'1',并且每个'线程'中的最新消息可以是来自该用户,或者该用户(另一个)派对总是由thread_recipient表示:

SELECT a.*,thread_recipient
  FROM messages a
  JOIN (SELECT IF(from_uid = '1',to_uid,from_uid) AS thread_recipient,
               MAX(time_added) AS recency
          FROM messages 
         WHERE (from_uid = '1' OR to_uid = '1')
      GROUP BY thread_recipient) b ON thread_recipient = (IF(a.from_uid = '1',a.to_uid,a.from_uid))
                             AND b.recency = a.time_added
 ORDER BY a.time_added DESC

但是我担心这不会正常工作,也许同时发送的邮件最终可能会被错误的用户返回?

我的WHERE条件错位了吗?

任何智慧都非常赞赏。

3 个答案:

答案 0 :(得分:3)

这是一个想法:拿下以下两个查询的UNION,然后得到 结果的最大日期。

SELECT id,to_uid AS other_party,time_added FROM messages WHERE from_uid = '1'

SELECT id,from_uid AS other_party,time_added FROM messages WHERE to_uid = '1'

执行以下操作时:

SELECT MAX(time_added),other_party
FROM (SELECT id,to_uid AS other_party,time_added FROM messages WHERE from_uid = '1'
      UNION
      SELECT id,from_uid AS other_party,time_added FROM messages WHERE to_uid = '1'
     ) MyMessages
GROUP BY other_party

您将获得与发送到的邮件相关联的最近时间 用户'1'对应的每个人。然后你可以加入 原始消息表的结果,以获得你想要的:

SELECT Messages.*
FROM (SELECT MAX(time_added) AS MaxTime,other_party
      FROM (SELECT id,to_uid AS other_party,time_added FROM messages WHERE from_uid = '1'
            UNION
            SELECT id,from_uid AS other_party,time_added FROM messages WHERE to_uid = '1'
           ) MyMessages
      GROUP BY other_party
     )
     JOIN Messages
     ON (Messages.time_added = MyMessages.MaxTime AND
          (Messages.to_uid = MyMessages.other_party AND Messages.from_uid = '1' OR
           Messages.from_uid = MyMessages.other_party AND Messages.to_uid = '1')
        )

答案 1 :(得分:1)

试试这个 - 我认为它可以更简单有效地为您提供所需的内容。

SELECT latest_time = MAX(a.time_added, b.time_added)
FROM messages a, messages b

LEFT JOIN messages a1
    ON a1.from_uid = a.from_id

-- find the case where the following doesn't exist
-- so you know there is nothing after b1
LEFT JOIN messages a2
    ON a2.from_uid = a.from_id
    AND a2.time_added > a1.time_added

LEFT JOIN messages b1
    ON b1.to_uid = b.to_id

LEFT JOIN messages b2
    ON b2.to_uid = b.to_id
    AND b2.time_added > b1.time_added

WHERE a.from_id = '1'
    AND b.to_id = '1'
    AND c1.id IS NULL
    AND c2.id IS NULL

ORDER BY a.time_added DESC

答案 2 :(得分:0)

好的,评论后 - 如果id是自动增量,则使用它而不是消息时间。但是你有条件确保不会将信息传递给错误的人。