mysql查询orderby groupby,

时间:2012-05-07 02:38:42

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

我的表格包含以下关键字段:commentidcommenttimeparentid

评论有两种类型,regularreplies。经常有parentid 0;回复与他们回复的纪念品相同。

我以为我已经把这个想法与group by和orderby弄明白但是我的想法没有用,而我现在正在努力,因为我对sql的了解还很简陋。

我希望它按时间显示DESC,除了我希望那些具有相同parentid并且在那个parentid内的那些,它们也可以按时间排序。我只允许一个级别的回复。

作为一个例子,我想按照顺序:

time3 commentid3 parentid0
time2 commentid2 parentid0
    parentid2 commentid4 time4 (this one is a reply)
    parentid2 commentid5 time5 (this one also reply)
time1 comment1 parentid0

我试过了SELECT * from comments GROUP BY parentid ORDER BY TIME DESC,但这没效果。如果需要,我可以添加另一列。任何建议,将不胜感激! THX。

3 个答案:

答案 0 :(得分:1)

我在这里做了一些假设。我假设你的commentid是一个自动递增的id,所以这意味着插入顺序将从最旧到最新。如果您没有使用自动递增ID,或者如果您对这些表有某种部分保存功能,则无法使用此功能。所以它有点脆弱。

我还假设如果父母是父母,那么parent_id为空。

SELECT commentid, comment, time, parent_id, if(parent_id = 0, commentid, parent_id) thread 
FROM comments  
ORDER BY thread desc, time asc

无论如何要添加更多信息。

Group By不是您想要使用的,因为它会将分组列的所有行分组到一行中。 Group By通常用于聚合计算,例如对行中的值进行计数或求和等。

编辑:

我更新了查询以按时间排序asc,这将首先放置常规注释,然后将父评论下面的回复从最旧到最新。

答案 1 :(得分:1)

你无法从sql查询中检索出“树状”结果(有很多方法,但它们在这里看起来并不实用)

您可以做的是从常规和回复中检索所有数据(这意味着如果他们有很多回复就会复制“常规”数据,并且您必须在获取数据后对其进行处理,以获得“树“结果”

结果将如此

regular.time, regular.commentid, replies.commentid, replies.time

如果常规没有评论,则replies.commentid和replylies.time将为null

查询(带有“自我左连接”)看起来就像那样(我移动了一些现在似乎毫无用处的字段)

select 
regular.time as regulartime,
regular.commentid as regularid, 
replies.commentid as repliesid, 
replies.time as repliestime
from comments regular
left join comments replies on replies.parentid = parent.commentid
where regular.parentid = 0
order by regular.time desc, replies.time asc 

按照你的例子,你应该得到

time3 commentid3 null       null
time2 commentid2 commentid4 time4 (this one is a reply)
time2 commentid2 commentid5 time5 (this one also reply)
time1 commentid1 null       nulll

答案 2 :(得分:1)

要获取两个数据层,您需要一个UNION,它只是原始注释的最顶层,另一个是任何可能的回复。查询第一部分的第一列将包含1或2以进行排序。这将用于将原始帖子浮动到组的顶部以用于给定问题...然后,所有回复将在此之后以自然顺序显示。

另外,为了保留原始日期/时间的正确分组,我保留原始帖子评论时间和'2'CommentType记录,这样他们确实保持与完全相同的原始时间开始基础分组,但抓住实际评论和RESPONSE的时间(别名“r”)用于各自的排序。

select
      PreQuery.*
   from
      ( select
              '1' as CommentType,
              c.Time as OriginalTime,
              c.CommentID StartingCommentID,
              c.Comment,
              c.Time as LastTime,
              c.CommentID as EndCommentID
           from
              comments c
           where
              c.ParentID = 0
        UNION ALL
        select 
              '2' as CommentType,
              c.Time as OriginalTime,
              c.CommentID StartingCommentID,
              r.Comment,
              r.Time as LastTime,
              r.CommentID as EndCommentID
           from
              comments c
                 join comments r
                    on c.CommentID = r.ParentID
           where
              c.ParentID = 0 ) PreQuery
   order by
      PreQuery.OriginalTime DESC,
      PreQuery.StartingCommentID,
      PreQuery.CommentType,
      PreQuery.LastTime

这应该会给你我认为你正在寻找的结果(略有修改)

CommentType  OriginalTime  StartingCommentID  Comment  LastTime  EndCommentID
1            Time3         ID3                Comm3    Time3     ID3  <-- ID 3 IS the start
1            Time2         ID2                Comm2    Time2     ID2  <-- ID 2 is the start of next
2            Time2         ID2                Comm4    Time4     ID4     <- ID4 is reply to orig ID2
2            Time2         ID2                Comm5    Time5     ID5     <- another reply to ID2
1            Time1         ID1                Comm1    Time1     ID1  <-- start of new comment ID1

因此,对于所有行,第2列和第3列将始终表示开始第一条注释的父ID ...对于注释类型为1的那些,注释,最后时间和结束注释ID是实际的起始评论的内容。对于注释类型= 2,最终注释,最后时间和结束注释将是RESPONSE记录的ID。