我有一个这样的postgres数据库,表格为 ids :
id INT PRIMARY KEY,
value TEXT,
parent_id INT REFERENCES ids DEFAULT NULL
我想查找此表中所有行的后代数量。因此对于树中的所有叶子,子树大小将为1。
我想用递归CTE做这个并写下这个:
WITH RECURSIVE r AS (
SELECT id, parent_id
from keyword
where id=1
UNION
SELECT k.id, k.parent_id
FROM keyword k
join r on k.parent_id = r.id)
select count(*) from r;
我只能计算某些身份的后代,而不是所有人。我试图在CTE中写入id by group,但它不起作用(大多数时候它给所有顶点的子树大小等于1)。
基于此表,
id | parent_id | value
----+-----------+--------
1 | | SELECT
2 | 1 | FROM
3 | 1 | WHERE
4 | 1 | ORDER
5 | 4 | BY
6 | 1 | GROUP
7 | 6 | BY
8 | 6 | HAVING
11 | | UPDATE
12 | 11 | SET
13 | 11 | WHERE
我希望得到:
id | subtree_size
-------+----------
1 | 11
2 | 1
6 | 3...
对于树中的所有id。
答案 0 :(得分:1)
CREATE TABLE keyword
( id INTEGER PRIMARY KEY
, parent_id INT REFERENCES keyword(id) DEFAULT NULL
, value TEXT
);
INSERT INTO keyword(id,parent_id, value) VALUES
( 1, NULL, 'SELECT')
,( 2, 1, 'FROM')
,( 3, 1, 'WHERE')
,( 4, 1, 'ORDER')
,( 5, 4, 'BY')
,( 6, 1, 'GROUP')
,( 7, 6, 'BY')
,( 8, 6, 'HAVING')
,( 11, NULL, 'UPDATE')
,( 12, 11, 'SET')
,( 13, 11, 'WHERE')
;
WITH RECURSIVE r AS (
SELECT id AS root -- <<== 'Anchor' the root
, id, parent_id
from keyword
-- where id=1
-- where parent_id IS NULL
WHERE id IN (1,2,6) -- <<== UPDATE
UNION
SELECT r.root -- <<== This is the trick: maintain the parent's root
, k.id, k.parent_id
FROM keyword k
join r on k.parent_id = r.id
)
select distinct k.value, r.root, count(*) AS cnt
from r
JOIN keyword k ON k.id = r.root
GROUP BY r.root, k.value
;