基于父子关系生成目录索引


Generate table of contents indexes based on parent-child relationships

我有一个名为task的表,它具有自关系来实现父子关系。

以下是表格的结构:

task (id, name, parent_id)

任何任务都可以有n子任务。

现在,在我看来,我必须以目录格式显示任务,第n级嵌套如下:

1. Grandfather
     1.1. Father
 1.2 Mother
    1.2.1 First Child
    1.2.1 Second Child
2. Grandfather's brother
 2.1 Grandfather's brothers son 
3. Grandfather's brother's wife

为了清楚起见,我为人际关系命名了这些任务,只是为了显示嵌套的层次结构级别。

我所做的是从数据库中选择所有任务,并开始像这样迭代:

foreach($tasks as $task)
{
//Get the hierarchy level here and print its index for example 1.1.2
}

我不知道如何将它们按1,2,3级排序,因为任何位于索引0的任务的实际位置都可能是3.1.2。

这可以在代码级别完成吗?或者有SQL建议吗?

感谢

在postgres中,您可以编写递归查询来读取分层数据结构的全部或部分。

CREATE TABLE task
(
  id integer NOT NULL DEFAULT,
  name text,
  parent_id integer,
  CONSTRAINT task_pkey PRIMARY KEY (id),
  CONSTRAINT task_parent_id_fkey FOREIGN KEY (parent_id)
      REFERENCES public.task (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
);
insert into task values
(1, 'grandfather', null),
(2, 'father', 1),
(3, 'mother', 1),
(4, 'first child', 3),
(5, 'second child', 3),
(6, 'grandfather''s brother', null),
(7, 'grandfather''s brother''s son', 6),
(8, 'grandfather''s brother''s wife', null);
with recursive relations(relation_id, parent_id, path) as(
    select id as relation_id, null::integer as parent, ARRAY[id]::integer[], from task where parent_id is null
    union 
    select id, task.parent_id, path || id from relations
    join task on task.parent_id = relation_id
)
select * from relations
order by path

输出为:

relation_id parent_id   path
1                       {1}
2           1           {1,2}
3           1           {1,3}
4           3           {1,3,4}
5           3           {1,3,5}
6                       {6}
7           6           {6,7}
8                       {8}

现在,在for循环中,您只需要一个数组,该数组会为路径中的每个新元素增加数字,当大小减少一时,会重置计数器。

这可能也可以在SQL和中完成

另一个需要考虑的选项是使用ltree而不是parent_id来存储关系。这将消除对CTE 的需求