2017-10-19 103 views
0

我在表中存储邻接树。我写了一个递归公用表表达式来查找树中每个节点的所有上升。 所以,当我写SELECT * FROM TREE;查找包含特定ID的所有数组Postgres

我得到这个:

id | ancestors 
----+--------------- 
    0 | {} <- ROOT 
    1 | {0} 
    2 | {0} 
    4 | {0} 
19 | {0} 
45 | {0} 
    3 | {0,1} 
    5 | {0,4} 
    6 | {0,4} 
    8 | {0,4} 
11 | {0,1} 
22 | {0,2} 
    7 | {0,4,5} 
    9 | {0,4,6} 

我想在树中的每个节点的所有后代的数量,因此对于每一个独特的ID我想找到阵列的数量祖先列包含这样的ID。

我可以做手工,但只有一个ID:

SELECT count(*) from tree 
WHERE 0 = any(tree.ancestors); 

对于此查询,如果与ID = 0节点是根,它应该给我的所有节点的数量减去1的树。

我试着写是这样的:

SELECT count(*) from tree 
WHERE id = any(tree.ancestors) 
group by id; 

但它实际上返回0行。

回答

1

您要搜索整个树的每个id,它与条件的自联接:

with tree(id, ancestors) as (
values 
    (0, '{}'::int[]), 
    (1, '{0}'), 
    (2, '{0}'), 
    (4, '{0}'), 
    (19, '{0}'), 
    (45, '{0}'), 
    (3, '{0,1}'), 
    (5, '{0,4}'), 
    (6, '{0,4}'), 
    (8, '{0,4}'), 
    (11, '{0,1}'), 
    (22, '{0,2}'), 
    (7, '{0,4,5}'), 
    (9, '{0,4,6}') 
) 

select t1.id, count(t2.*) 
from tree t1 
join tree t2 on t1.id = any(t2.ancestors) 
group by 1 
order by 1 

id | count 
----+------- 
    0 | 13 
    1 |  2 
    2 |  1 
    4 |  5 
    5 |  1 
    6 |  1 
(6 rows) 

注意,如果你想获得的所有ids(与那些别,你应该使用left join t出现在ancestors)。

相关问题