我想知道哪种方法是提取树结构数据的有效方法
我有一张像这样的桌子
表:食品类别
----------------------------------------------------------
| id | parent | category_name |
----------------------------------------------------------
| 1 0 Food |
| 2 1 Veg Items |
| 3 1 Non Veg Items |
| 4 2 Carrots |
| 5 2 Greens |
| 6 2 Milk |
| 7 3 Poultry |
| 8 3 Seafood |
| 9 7 Chicken |
| 10 8 Fish |
| 11 8 Prawns |
----------------------------------------------------------
树形结构的深度在这里不受限制,它可以达到任何级别的
我想在下面买这些
array(Food'=>array( 'Veg Items'=>array('carrots'=>array(),'Greens'=>array(),'Milk'=>array()),
'Non Veg Items'=>array(
'Poultry'=>array('Chicken'=>array()),
'Seafood'=>array('Fish'=>array(),'Prawns'=>array())
)
)
)
这有可能获取这种结构化数组吗?
我使用的是postgresql,但在这方面我不是很熟练,阅读了SO和其他文章中的许多问题,解释了类似的概念,但我无法准确理解。
感谢您的帮助。
在Postgres中,您可以使用递归CTE:来实现这一点
WITH RECURISVE recCTE AS
(
--Recursive seed
SELECT
parent,
id as child,
0 as depth
parent || '>' || id as path
FROM
food_categories
WHERE parent = 0 --restricting to the top most node of your hierarchy
UNION ALL
--Recursive statement
SELECT
recCTE.child as Parent,
fc.id as child,
recCTE.depth + 1 as Depth,
path || '>' || fc.id as path
FROM
recCTE
INNER JOIN food_categories fc
ON recCTE.child = fc.parent
WHERE
depth <=20 --Set this just in case we get into an infinite cycle
)
SELECT * FROM recCTE;
递归CTE包括三个部分:
- 递归种子,它是层次结构的起点。我猜在你的情况下,它是
0
的parent
- 递归术语是递归CTE的一部分,它引用回自己,连接到包含层次结构的表
- 告诉Postgres如何从CTE中进行选择的最后一个SELECT
这将返回层次结构中的每个节点,它的深度,它的父节点,以及从根节点0
到最低子节点的路径,而不考虑深度(最多20个,因为我们在WHERE
中坚持了这一点)。
您可以将其与json_agg
和row_to_json
等结合起来,将其转换为代码中更可用的对象,或者保持原样,通过最后一条SELECT
语句从中获取所需的位。如果你对这条路线感兴趣,你可以看看这个很棒的解释和例子。