从postgresql中获取树结构化数据

时间:2016-04-11 12:23:38

标签: php database postgresql

我弄清楚哪种是获取树状结构数据的有效方法

我有一张这样的表

表:food_categories

var button = $('#buttonAddContact');
button.addEventListener('click', function(){
    var obj = new Contact(); // fill it now
    array.append(obj);
});

树结构深度不限于此,它可以进入任何级别

我想要像下面那样获取这些

----------------------------------------------------------
| 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                         |
----------------------------------------------------------

这可以获取这种结构化数组吗?

我正在使用postgresql,但我不是很方便,在SO和其他解释类似概念的文章中阅读了很多问题,但我无法准确。

帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

在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分为三部分:

  1. 递归种子,它是层次结构的起点。我猜你的情况是parent 0
  2. 递归术语,它是引用回自身的递归CTE的一部分,连接到包含层次结构的表
  3. 告诉Postgres如何从您的CTE中选择的最终SELECT。
  4. 这将返回层次结构中的每个节点,它的深度,它的父节点,以及从根节点0到最低子节点的路径,无论深度如何(因为我们在{{{ 1}})。

    您可以将其与WHEREjson_agg等结合使用,将其转换为代码中更实用的对象,或保留原样以便从中获取所需的位数row_to_json声明。如果您对此路线感兴趣,可以查看this great explaination and example