mysql组并对UNION进行排序

时间:2011-04-17 22:11:18

标签: mysql

在我的留言簿中,我有2个表:messagesreplies。 现在,我希望获取按ID分组的所有消息(意味着消息和相应的回复将被分组/一起)并按日期排序DESC(最新的消息将是第一个;如果消息是最早的消息,但相应的回复是所有消息中的最新消息,该组将位于表格的顶部),而回复将按日期ASC排序(最顶层的回复)。 这里我的mysql查询运行良好,除了它没有按日期ASC

排序回复
SELECT msg.id as id, msg.comment, msg.date_added as date_added, 0 as is_reply
  FROM messages AS msg 
UNION 
SELECT reply.msg_id as id, reply.comment, reply.date_added as date_added, 1 as is_reply
  FROM pg_reply as reply 

GROUP BY id 
ORDER BY date_added DESC, is_reply ASC 

is_reply ASC并没有像我想的那样完成工作

reply.msg_id指定回复的父级(messages.id

的ID

结果应如何>

- message A
- oldest reply B 
- old reply C
- new reply Z  // this is the newest message in the guestbook 
- newer message E // is newer than A but older than the newest message in the guestbook, which is Z
- reply F // (this reply is newer than all messages but message Z)

4 个答案:

答案 0 :(得分:2)

对于这个答案,我将假设reply.msg_id是原始邮件的链接字段。

SELECT id, comment, date_added, is_reply FROM (
  SELECT 
    msg.id as id
    , msg.comment
    , msg.date_added as date_added
    , 0 as is_reply
    FROM messages AS msg 
UNION 
  SELECT 
    reply.msg_id as id
    , reply.comment
    , reply.date_added as date_added
    , 1 as is_reply
  FROM pg_reply as reply ) AS allmsg
ORDER BY id DESC, is_reply, date_added DESC

这可以假设msg_id是一个自动增量字段,而较新的id也有一个较新的date_added时间戳。

对原始代码的备注
在您的原始代码中

GROUP BY id 
ORDER BY date_added DESC, is_reply ASC

GROUP BY隐含地在id ASC下单;以下ORDER BY 覆盖date_added首先排序is_reply,然后date_added秒排序。
但是,如果datetimeGROUP BY,那么两个帖子具有相同时间的机会是远程的(特别是对于回复,需要时间来编写), 所以二阶条款几乎没有被使用过。

只有在select中有汇总功能时才应使用

SUM,例如COUNTselect distinct a,b,c from table1 where ...

如果您要从选择不使用组中删除重复项,请在{{1}}

中使用distinct

答案 1 :(得分:1)

类似的解决方案:

SELECT sort, project, reviewdate, reviewby, subject, venue, filename, remarks1, remarks2, url
FROM (

   SELECT '1' AS sort, project, last_updated AS reviewdate, reviewby, concat( project, '(', 
    TYPE , '): ', subject ) AS subject, venue, filename, remarks1, remarks2, concat( project, '/', 
    TYPE , '/', filename ) AS url
   FROM `upload_cmg` 
   WHERE (
     (
      subject LIKE '%prt%'
      OR project LIKE '%prt%'
      OR TYPE LIKE '%prt%'
     )
     AND (
      subject LIKE '%mouda%'
      OR project LIKE '%mouda%'
      OR TYPE LIKE '%mouda%'
     )
   )
   UNION SELECT '2' AS sort, project, last_updated AS reviewdate, reviewby, concat( project, '(', 
    TYPE , '): ', subject ) AS subject, venue, filename, remarks1, remarks2, concat( project, '/', 
    TYPE , '/', filename ) AS url
   FROM `upload_cmg` 
   WHERE subject LIKE '%mouda%'
   GROUP BY url
) AS vin
ORDER BY sort, reviewdate DESC 

答案 2 :(得分:0)

我建议在两者中添加一个消息父字段,然后将其作为主要排序进行排序,然后将日期作为排序后的排序。否则,您将看到与回复之间发布的其他消息混淆的回复。您可以将非回复消息的父消息作为其自身。

答案 3 :(得分:0)

试试这个:

SELECT id, comment, date_added, is_reply
FROM (
    SELECT msg.id as id, msg.comment, msg.date_added as date_added, 0 as is_reply
      FROM messages AS msg 
    INNER JOIN pg_reply as reply
    ON reply.msg_id = msg.id
    GROUP BY msg.id, msg.comment, msg.date_added, 0 as is_reply
    ORDER BY CASE WHEN MAX(reply.date_added) > msg.date_added THEN MAX(reply.date_added) ELSE msg.date_added END DESC
    UNION 
    SELECT reply.msg_id as id, reply.comment, reply.date_added as date_added, 1 as is_reply
    FROM pg_reply as reply 
    ORDER BY date_added ASC ) a
ORDER BY id