mysql分组问题

时间:2010-09-15 02:16:52

标签: sql mysql group-by

嘿伙计们,快速提问。我有一张消息表。

有两种类型的消息:

  • 具有唯一组ID的邮件
  • 自主信息

与至少一条其他消息具有相同组ID的消息 - 这些消息在呈现时我想要组合在一起。分组的消息是带有答复的消息。我想要做的是创建一个查询,以便将分组的消息放在一个位置,在该位置,该组的最早/根消息将按时间顺序与其余消息相关联,而不管回复的输入时间。 / p>

我当前的查询是这样的,显然只按时间顺序对邮件进行排序。

  SELECT timestamp, 
         user, 
         message, 
         group_id 
    FROM messages 
   WHERE topic_id = ? 
ORDER BY timestamp DESC 
   LIMIT 10

有人有任何建议吗?

1 个答案:

答案 0 :(得分:2)

这个怎么样?

SELECT m.timestamp, m.user, m.message, m.group_id, g.grp_timestamp
  FROM messages AS m JOIN
       (SELECT group_id, MIN(timestamp) AS grp_timestamp
          FROM messages
         GROUP BY group_id) AS g ON m.group_id = g.group_id
 WHERE m.topic_id = ?
 ORDER BY g.grp_timestamp, g.group_id, m.timestamp;

逻辑是识别子查询中每个group_id的最早时间戳(假设没有响应的消息分配了有效的group_id),然后先按组时间戳排序,然后按组ID排序(如果是两个组,则排序)以某种方式以相同的时间戳结束,消息仍然正确排序),然后是消息时间戳。

您可能也希望将WHERE子句推送到子选择中。


如果您想先获得最新的消息,那么基本上,您将DESC应用于适当位置的ORDER BY子句。

SELECT m.timestamp, m.user, m.message, m.group_id, g.grp_timestamp
  FROM messages AS m JOIN
       (SELECT group_id, MIN(timestamp) AS grp_timestamp
          FROM messages
         GROUP BY group_id) AS g ON m.group_id = g.group_id
 WHERE m.topic_id = ?
 ORDER BY g.grp_timestamp DESC, g.group_id, m.timestamp DESC;

您可能希望首先显示具有最新响应的组;在这种情况下,您需要将聚合从MIN调整到MAX:

SELECT m.timestamp, m.user, m.message, m.group_id, g.grp_timestamp
  FROM messages AS m JOIN
       (SELECT group_id, MAX(timestamp) AS grp_timestamp
          FROM messages
         GROUP BY group_id) AS g ON m.group_id = g.group_id
 WHERE m.topic_id = ?
 ORDER BY g.grp_timestamp DESC, g.group_id, m.timestamp;

只要您按照时间顺序显示响应,我认为这就是诀窍。如果响应必须以反向时间顺序出现,并且原始消息首先出现,则您会遇到一些困难。如果您在消息表中为“leader”和“follower”标记了“L”的消息,那么您可以使用该列进行排序。如果您必须动态确定消息是否是领导者或追随者,则必须更加努力。