我有一个带有两列的表(我们称它为人)
id, parent_id
我想枚举每条记录,但为parent_id不为null的每条记录分配一个子编号,例如
id | parent_id| number
1 NULL 1
2 NULL 2
3 2 2.1
4 NULL 3
5 4 3.1
父级应该有连续的数字,按id
的顺序排列,子级-每个父级以1开头的连续数字。父母可能有很多孩子。但是孩子不能生孩子,因此3.3.3并非如此。
实现此目标的最佳方法是什么?
答案 0 :(得分:1)
您应该在两个单独的查询中为父母和孩子计算行号,合并结果并连接适当的数字:
with numbers as (
select *, row_number() over (partition by parent_id order by id) as rn
from person
where parent_id is not null
union all
select *, row_number() over (order by id) as rn
from person
where parent_id is null
)
select n1.id, n1.parent_id, concat_ws('.', n2.rn, n1.rn) as number
from numbers as n1
left join numbers as n2 on n2.id = n1.parent_id
order by n1.id
id | parent_id | number
----+-----------+--------
1 | | 1
2 | | 2
3 | 2 | 2.1
4 | | 3
5 | 4 | 3.1
(5 rows)
答案 1 :(得分:1)
我只是使用窗口函数来做到这一点:
select t.*,
concat_ws('.',
dense_rank() over (order by coalesce(parent_id, id)),
(case when parent_id is not null
then row_number() over (partition by parent_id order by id)
end)
)
from person t
order by id;