2

我有一个包含以下关键字段的表:commentid, comment, time,parentid

评论有两种类型,regularreplies。正则有parentid 0;回复的 parentid 等于他们回复的 commentid。

我以为我已经通过 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了,但这没有用。如果需要,我可以添加另一列。任何建议,将不胜感激!谢谢。

4

3 回答 3

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 排序,这将把常规评论放在第一位,然后是父评论下方的回复,从最旧到最新。

于 2012-05-07T03:05:53.933 回答
1

您无法从 sql 查询中检索“树状”结果(有很多方法,但它们似乎在这里实际上不可用)

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

结果看起来像这样

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

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

查询(带有“self left join”)看起来像这样(我移动了一些现在似乎没用的字段)

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
于 2012-05-07T08:50:34.737 回答
1

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

此外,为了保留按原始日期/时间进行的正确分组,我将原始发表评论时间与“2”评论类型记录一起保留,因此它们确实以完全相同的原始时间开始分组,但获取实际评论和时间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 是来自开始评论。对于comment type = 2,最终评论、最后一次和结束评论将是RESPONSE记录的ID。

于 2012-05-07T11:15:16.097 回答