PostgreSQL在分层查询结果中排序记录

时间:2012-11-08 22:36:39

标签: sql postgresql hierarchy postgresql-9.1

我正在尝试做一些应该简单的事情,但我错过了一些东西。我试图返回分组和有序的一些分层数据。 a而不是试图解释,我附上一张图片......听说他们值得一千个字:

Order of data in the database vs the order the resultset needs to be in.

请注意,硬编码值不合适,因为主要的选择标准是article_id,然后沿着第一个“根级别”article_comment_id的行排序,后面跟着它的子节点,然后是下一个'根节点level'article_comment_id及其子节点。

我提供了一个示例表和数据,以便您可以看到我的意思,以及显示我想要实现的内容的屏幕截图。

CREATE TABLE test_comment
(
  article_comment_id bigserial NOT NULL,
  article_id bigint NOT NULL,
  parent_comment_id bigint,
  comment text NOT NULL,
  comment_depth integer,
  CONSTRAINT test_comment_pkey PRIMARY KEY (article_comment_id )
)

INSERT INTO test_comment (article_comment_id, article_id, parent_comment_id, comment, comment_depth)
VALUES
 (1, 100, 0, 'First Root Comment', 0)
,(5, 100, 0, 'Second Root Comment', 0)
,(2, 100, 1, 'Reply 1 to Root Comment', 1)
,(3, 100, 2, 'Reply 2 to Reply 1', 2)
,(4, 100, 3, 'Reply 3 to Reply 2', 3)
,(6, 100, 2, 'Reply 4 to Reply 1', 2)
,(7, 100, 5, 'Reply 5 to Second Root Comment', 1);

我试过这个,但它没有提供正确的顺序:

with recursive comment_list(article_comment_id, parent_comment_id, comment, article_id) AS (
    select c.article_comment_id, c.parent_comment_id, c.comment, c.article_id
    from test_comment c
    where article_id = 100
  union
    select c.article_comment_id, c.parent_comment_id, c.comment, c.article_id
    from test_comment c, comment_list cl
    where c.article_comment_id = cl.article_comment_id
    )
    select * from comment_list;

这个PostgreSQL特定的查询是否可以与JPA一起使用?

1 个答案:

答案 0 :(得分:4)

您需要将根文章ID“携带”到每个节点并计算层次结构级别才能获得该排序:

with recursive comment_list(article_comment_id, parent_comment_id, comment, article_id, level, root_id) AS (
    select c.article_comment_id, 
           c.parent_comment_id, 
           c.comment, 
           c.article_id, 
           0 as level,
           article_comment_id as root_id 
    from test_comment c
    where article_id = 100
      and parent_comment_id = 0

  union

    select c.article_comment_id, 
           c.parent_comment_id, 
           c.comment, 
           c.article_id, 
           cl.level + 1,
           cl.article_comment_id 
    from test_comment c
       join comment_list cl on c.parent_comment_id = cl.article_comment_id
)
select article_comment_id, 
     parent_comment_id, 
     comment, 
     article_id
from comment_list
order by root_id, level;

SQLFiddle:http://www.sqlfiddle.com/#!12/af0d6/4

(顺便说一句:你在联盟的递归部分中你的连接错了)