嵌套回复的评论

时间:2015-02-18 09:51:18

标签: sql postgresql

我的数据库看起来像:

id
reply_to
text

数据如:

id          1           2           3       4       5
reply_to    NULL        1           1       2       1
text        WOW         MUCH WOW    WHAT?   0_0     ?

NULL在哪里 - 顶级评论。

我希望得到类似的内容:

#1 WOW
    #2 MUCH WOW
        #4 WHAT?
    #3 0_0
    #5 ?
...

因此,查询应按该顺序返回数据:1, 2, 4, 3, 5

那么,是否可以从数据库中选择已排序的注释,或者我应该在查询后对它们进行排序?

更新
我忘记了从另一个数据库获取用户昵称很重要 所以,数据库:

id
reply_to
text
topic_id
user_id

topic_id = 1中的WHERE一切正常,但是另一个表中的user_nickname呢?

1 个答案:

答案 0 :(得分:2)

这是一个递归查询的简单案例:

with recursive replies as (
   select id, reply_to, text, 0 as level, array[id] as sort_path
   from threads --<< replace with your real table name
   where reply_to is null
   union all
   select c.id, c.reply_to, c.text, p.level + 1, p.sort_path||c.id
   from threads c
     join replies p on p.id = c.reply_to
)
select rpad(' ', level * 2)||'#'||id||' '||text
from replies
order by sort_path

with部分称为common table expression,并递归检索所有回复。

外部选择然后简单地格式化显示并缩进线条。

sort_path列用于正确排序最终结果。

如果希望以正确的顺序返回ID,只需使用:

with recursive replies as (
   select id, array[id] as sort_path
   from threads 
   where reply_to is null
   union all
   select c.id, p.sort_path||c.id
   from threads c
     join replies p on p.id = c.reply_to
)
select id
from replies
order by sort_path

在最后的select语句中。要了解数组的用途,您可能希望在查询工具中也显示它,然后这就变得很明显了。