2012-05-07 47 views
2

我有以下主要字段的表:commentidcommenttimeparentidMySQL查询排序依据GROUPBY,

的意见有两种类型,regularreplies的。经常有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但这并没有工作。如果需要,我可以添加另一列。任何建议,将不胜感激!谢谢。

回答

1

我在这里做了一些假设。我假设您的纪念是一个自动递增的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通常用于聚合计算,如计数或行中的值相加,等

编辑:

我更新了查询按时间递增排序,这将首先把常规注释,然后答复低于从最旧到最新的家长评论。

+0

线程是如何设置的?它与纪念相同吗?如果我理解正确,它会输出原始线程。我试图模仿disqus,livefyre的评论时间递减,但回复显示在他们回复的评论下方。缩进只是一个格式问题,所以我只需要在各自的父注释下插入回复。 – user1260310

+0

线程可能不是最好的单词,但它在select子句中由条件设置。因此,如果parent_id为空,我们将使用纪念的线程ID。这只是为了整理所有评论。 – Gohn67

+0

为了澄清,线程不是真正的列,它只是if函数的别名。我们使用线程在这里作弊,因为我们假设线程按从最旧到最新的顺序输入,然后每个分组注释都按时间列排序。 – Gohn67

1

你不能从SQL查询检索“树状”的结果(当然有办法,但他们似乎并不在这里实际可用)

你可以做的是从中检索所有提交的数据定期和回复(这意味着,如果“常规”数据将被复制,如果他们有很多回复,并且在获得数据后必须对待它们,以获得“树”结果)

结果看起来像那样

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

如果经常没有评论,reply.comment ID和回复。时间将是无效

查询(用“自左连接”)将看起来像(我有些感动字段现在似乎是无用的)

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 
+0

你是否建议两张表,经常和回复? – user1260310

+0

不,一个表,但别名在查询 –

+0

我必须阅读别名,因为我不立即理解语法。 – user1260310

1

要获取这两个数据层,您只需要一个UNION即原始注释的最顶层,另一个用于任何POSSIBLE回复。查询的第一部分的第一列将保留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 

所以,对于所有行,第二和第三列将始终代表正在启动父ID第一条评论......对于评论类型= 1的评论,评论,上次评论和最终评论ID是开始评论的实际内容。对于评论类型= 2,最终评论,上次评论和结束评论将是RESPONSE记录的ID。