【发布时间】:2022-01-19 15:03:11
【问题描述】:
我有一个看起来像这样的闭包表:
| id | childrenId | parentId | childrenName | depth | | |
|-----|--------------------------------------|--------------------------------------|--------------|-------|---|
| -- | ---------- | -------- | ------------ | ----- | | |
| 98 | 8b4a5764-37ec-4ef4-8a3e-570c2e9920dd | 8b4a5764-37ec-4ef4-8a3e-570c2e9920dd | country1 | 0 | | |
| 99 | 8b4a5764-37ec-4ef4-8a3e-570c2e9920dd | | | country1 | 1 | | |
| 100 | 5d95fb4a-abd4-48e6-81e3-c40bc420410c | 5d95fb4a-abd4-48e6-81e3-c40bc420410c | country2 | 0 | | |
| 101 | 5d95fb4a-abd4-48e6-81e3-c40bc420410c | | | country2 | 1 | | |
| 102 | cd8bbeca-1a30-4a13-893a-1e8f95571924 | cd8bbeca-1a30-4a13-893a-1e8f95571924 | site2 | 0 | | |
| 105 | 1c58f75c-8b60-473c-b5b9-956d08ffb669 | 1c58f75c-8b60-473c-b5b9-956d08ffb669 | site1 | 0 | | |
| 106 | 1c58f75c-8b60-473c-b5b9-956d08ffb669 | 5d95fb4a-abd4-48e6-81e3-c40bc420410c | site1 | 1 | | |
| 107 | 1c58f75c-8b60-473c-b5b9-956d08ffb669 | | | site1 | 2 | | |
| 108 | 51b31260-a335-46f4-94d2-130ffc7e009e | 51b31260-a335-46f4-94d2-130ffc7e009e | building1 | 0 | | |
| 109 | 51b31260-a335-46f4-94d2-130ffc7e009e | cd8bbeca-1a30-4a13-893a-1e8f95571924 | building1 | 1 | | |
| 112 | 746d0ac8-144a-401a-b26b-8313a4667b78 | 746d0ac8-144a-401a-b26b-8313a4667b78 | floor1 | 0 | | |
| 113 | 746d0ac8-144a-401a-b26b-8313a4667b78 | 51b31260-a335-46f4-94d2-130ffc7e009e | floor1 | 1 | | |
| 114 | 746d0ac8-144a-401a-b26b-8313a4667b78 | cd8bbeca-1a30-4a13-893a-1e8f95571924 | floor1 | 2 | | |
| 117 | cd8bbeca-1a30-4a13-893a-1e8f95571924 | 5d95fb4a-abd4-48e6-81e3-c40bc420410c | site2 | 1 | | |
| 118 | 51b31260-a335-46f4-94d2-130ffc7e009e | 5d95fb4a-abd4-48e6-81e3-c40bc420410c | building1 | 2 | | |
| 119 | 746d0ac8-144a-401a-b26b-8313a4667b78 | 5d95fb4a-abd4-48e6-81e3-c40bc420410c | floor1 | 3 | | |
| 120 | cd8bbeca-1a30-4a13-893a-1e8f95571924 | | | site2 | 2 | | |
| 121 | 51b31260-a335-46f4-94d2-130ffc7e009e | | | building1 | 3 | | |
| 122 | 746d0ac8-144a-401a-b26b-8313a4667b78 | | | floor1 | 4 | | |
| 123 | af574093-8ec2-42ac-9779-d3894cb329fc | af574093-8ec2-42ac-9779-d3894cb329fc | room1 | 0 | | |
| 124 | af574093-8ec2-42ac-9779-d3894cb329fc | 746d0ac8-144a-401a-b26b-8313a4667b78 | room1 | 1 | | |
| 125 | af574093-8ec2-42ac-9779-d3894cb329fc | 51b31260-a335-46f4-94d2-130ffc7e009e | room1 | 2 | | |
| 126 | af574093-8ec2-42ac-9779-d3894cb329fc | cd8bbeca-1a30-4a13-893a-1e8f95571924 | room1 | 3 | | |
| 127 | af574093-8ec2-42ac-9779-d3894cb329fc | 5d95fb4a-abd4-48e6-81e3-c40bc420410c | room1 | 4 | | |
| 128 | af574093-8ec2-42ac-9779-d3894cb329fc | | | room1 | 5 | | |
使用一些“带有递归”的 sql(抓取:here):
with recursive
recursive_tree_parents as
(
select "childrenId",'{}'::uuid[] as parents, "childrenName", "depth"
from "ResourcesTree"
-- Top filter = depth
where "parentId" isnull and depth = 1
union all
select c."childrenId",parents || c."parentId", c."childrenName", p.depth+1
from recursive_tree_parents p
join "ResourcesTree" c
on c."parentId" = p."childrenId"
where c."parentId" != c."childrenId"
and c.depth = 1
and not c."childrenId" = any(parents)
),
recursive_tree_childrens as
(
select c."parentId",
json_agg(jsonb_build_object('Name', c."childrenName")
||jsonb_build_object('childrenId', c."childrenId"))::jsonb as js,
tree.depth
from recursive_tree_parents tree
join "ResourcesTree" c using("childrenId")
where c."childrenId" in
( SELECT distinct "childrenId"
FROM "ResourcesTree" b
-- Bottom Filter = tree.depth
where c.depth = 1 and tree.depth < 6
)
and not c."childrenId" = any(parents)
group by c."parentId", tree.depth
--this seems to do nothing
union all
select c."parentId",
jsonb_build_object('Name', c."childrenName")
||jsonb_build_object('id', c."childrenId")
|| jsonb_build_object('Childrens', js) as js,
tree.depth
from recursive_tree_childrens tree
join "ResourcesTree" c on c."parentId"::text = tree.js->> 'childrenId'
--end
),
final_step as
(
select *
from recursive_tree_childrens
order by depth desc
)
select * from final_step
我设法在下面获得了类似的东西:
| parentId | js | depth | | |
|--------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|-------|---|
| -------- | -- | ----- | | |
| 746d0ac8-144a-401a-b26b-8313a4667b78 | [{"Name": "room1", "childrenId": "af574093-8ec2-42ac-9779-d3894cb329fc"}] | 5 | | |
| 51b31260-a335-46f4-94d2-130ffc7e009e | [{"Name": "floor1", "childrenId": "746d0ac8-144a-401a-b26b-8313a4667b78"}] | 4 | | |
| cd8bbeca-1a30-4a13-893a-1e8f95571924 | [{"Name": "building1", "childrenId": "51b31260-a335-46f4-94d2-130ffc7e009e"}] | 3 | | |
| 5d95fb4a-abd4-48e6-81e3-c40bc420410c | [{"Name": "site1", "childrenId": "1c58f75c-8b60-473c-b5b9-956d08ffb669"}, {"Name": "site2", "childrenId": "cd8bbeca-1a30-4a13-893a-1e8f95571924"}] | 2 | | |
| | | [{"Name": "country1", "childrenId": "8b4a5764-37ec-4ef4-8a3e-570c2e9920dd"}, {"Name": "country2", "childrenId": "5d95fb4a-abd4-48e6-81e3-c40bc420410c"}] | 1 | | |
我想以某种方式递归地将所有内容合并到一行中,以获得如下所示的 json:
[[{"Name":"country1","childrenId":"8b4a5764-37ec-4ef4-8a3e-570c2e9920dd"},{"Name":"country2","childrenId":"5d95fb4a-abd4-48e6-81e3-c40bc420410c","childrens":[{"Name":"site1","childrenId":"1c58f75c-8b60-473c-b5b9-956d08ffb669"},{"Name":"site2","childrenId":"cd8bbeca-1a30-4a13-893a-1e8f95571924","childrens":[{"Name":"building1","childrenId":"51b31260-a335-46f4-94d2-130ffc7e009e","childrens":[{"Name":"floor1","childrenId":"746d0ac8-144a-401a-b26b-8313a4667b78","childrens":[{"Name":"room1","childrenId":"af574093-8ec2-42ac-9779-d3894cb329fc"}]}]}]}]}]]
有人想通过查询来实现吗?
谢谢
【问题讨论】:
标签: json postgresql