我将邻接树存储在表中。我编写了一个递归的Common Table表达式来查找树中每个节点的所有优先级。
所以当我写SELECT * FROM TREE;
我明白了:
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行。
答案 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)
请注意,如果您想要获取所有left join
(ids
中未显示的内容),则应使用ancestors
。