使用树顺序从表中选择行

时间:2010-09-14 13:26:40

标签: sql postgresql tree

我有表女巫包含字段:id,parent_id,name(etc。)

我想在“树旅行顺序”中订购此表,即。

id  parent_id
1,  0
3,  1
5,  1

2,  0
8,  2

4,  0
9,  4

(...)

简而言之:取根节点,追加所有子节点,下一个根节点追加子节点等。

4 个答案:

答案 0 :(得分:10)

根据您的描述,我假设您的意思是广度优先,可以使用WITH RECURSIVE查询(PostgreSQL 8.4+)轻松完成:

WITH RECURSIVE tree 
AS 
(
    SELECT 
        node_name, id, parent_id, NULL::varchar AS parent_name 
    FROM foo 
    WHERE parent_id IS NULL 
    UNION
    SELECT 
        node_name, f1.id, f1.parent_id, tree.node_name AS parent_name 
    FROM 
        tree 
        JOIN foo f1 ON f1.parent_id = tree.id
) 
SELECT node_name, empno, parent_id, node_name FROM tree;

您还可以使用以下SQL来使用深度优先顺序:

WITH RECURSIVE tree 
AS 
(
    SELECT 
        node_name, id, parent_id, NULL::varchar AS parent_name, id::text AS path 
    FROM foo WHERE parent_id IS NULL 
    UNION
    SELECT 
        node_name, f1.id, f1.parent_id, tree.node_name AS parent_name, tree.path || '-' || f1.id::text AS path 
    FROM 
        tree 
        JOIN foo f1 ON f1.parent_id = tree.id
) 
SELECT node_name, empno, parent_id, node_name, path FROM tree ORDER BY path;

答案 1 :(得分:4)

正如 synergetic 所注意到的, Diogo Biazus 提供的深度优先顺序的解决方案不适用于具有不同位数的id

但您可以使用此解决方案,它使用整数数组:

WITH RECURSIVE tree 
AS 
(
    SELECT 
        node_name, id, parent_id, NULL::varchar AS parent_name, array[id] AS path 
    FROM foo WHERE parent_id IS NULL 
    UNION
    SELECT 
        node_name, f1.id, f1.parent_id, tree.node_name AS parent_name, tree.path || f1.id AS path 
    FROM 
        tree 
        JOIN foo f1 ON f1.parent_id = tree.id
) 
SELECT node_name, empno, parent_id, node_name, path FROM tree ORDER BY path;

答案 2 :(得分:0)

您也可以使用优秀的LTree模块,但需要重新整理数据。

答案 3 :(得分:-2)

SELECT * FROM table ORDER BY id,parent_id

这应该按照查询中的顺序排列我的列。

除非你的意思是GROUP这些项目,我认为你这样做,然后使用

SELECT * FROM table ORDER BY id GROUP BY parent_id

我还建议你阅读这篇文章:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/