2017-10-19 102 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)。

相關問題