抱歉,使用下一个结构时,我遇到了一些关于您的查询的问题。
1,0,'Food',2,21
2,0,'Beverages',22,27
3,1,'Appetizer',3,8
4,3,'Soup',9,14 -- Parent soup is 3 instead 1
5,1,'Pizza',15,20
6,2,'Wines',23,24
7,2,'Soft drinks',25,26
8,3,'Nachos & salsa',4,5
9,3,'Kentucky chicken wings',6,7
10,4,'Broth',10,11
11,4,'Tomato soup',12,13
12,5,'Americana',16,17
13,5,'Margherita',18,19
结果是:
tree | level | path
------------------------------+-------+-------------------------------------------
Beverages | 0 | {Beverages}
|__Soft drinks | 1 | {Beverages,"Soft drinks"}
|__Wines | 1 | {Beverages,Wines}
Food | 0 | {Food}
|__Appetizer | 1 | {Food,Appetizer}
|__|__Kentucky chicken wings | 2 | {Food,Appetizer,"Kentucky chicken wings"}
|__|__Nachos & salsa | 2 | {Food,Appetizer,"Nachos & salsa"}
|__|__Soup | 2 | {Food,Appetizer,Soup}
|__|__|__Broth | 2 | {Food,Appetizer,Soup,Broth}
|__|__|__Tomato soup | 3 | {Food,Appetizer,Soup,"Tomato soup"}
|__Pizza | 1 | {Food,Pizza}
|__|__Americana | 2 | {Food,Pizza,Americana}
|__|__Margherita | 2 | {Food,Pizza,Margherita}
(13 rows)
使用您相同的逻辑,这可能会更好:
。
WITH RECURSIVE t AS (
SELECT f.id, f.name, f.parent, f.lft, f.rgt, array[f.name] AS path, 0 AS level
FROM food f
WHERE f.parent = 0
UNION ALL
SELECT f.id, f.name, f.parent, f.lft, f.rgt, t.path || f.name, level+1
FROM food f JOIN t ON f.parent = t.id
)
SELECT ( '[' || string_agg( json, '' ) || ']' ) :: json FROM (
select
'{"name":'||to_json( name ) ||
case lead( level, 1 ) OVER( ORDER BY path )
when level then '},'
when level + 1 THEN ', "items":['
else
'}' ||
case
when lead( level ) OVER( ORDER BY path ) < level THEN
repeat( ']}', level - lead( level ) OVER( ORDER BY path ) ) || ','
else repeat( ']}', level )
end
end as json
from t
) s1;
缩进???或许以后会有...
编辑
添加代码演示
http://sqlfiddle.com/#!15/187e5/1