我的桌子上有以下数据:
id | parent_id | short_name
----+-----------+----------------
6 | 5 | cpu
7 | 5 | ram
14 | 9 | tier-a
15 | 9 | rfc1918
16 | 9 | tolerant
17 | 9 | nononymous
13 | 12 | cloudstack
5 | 13 | virtualmachine
8 | 13 | volume
9 | 13 | ipv4
3 | | domain
4 | | account
12 | | vdc
(13 rows)
使用递归查询时,它看起来像这样:
with recursive tree ( id, parent_id, short_name, deep_name ) as (
select resource_type_id, parent_resource_type_id, short_name, short_name::text
from resource_type
where parent_resource_type_id is null
union all
select rt.resource_type_id as id, rt.parent_resource_type_id, rt.short_name,
tree.deep_name || '.' || rt.short_name
from tree, resource_type rt
where tree.id = rt.parent_resource_type_id
)
select * from tree;
id | parent_id | short_name | deep_name
----+-----------+----------------+-----------------------------------
4 | | account | account
3 | | domain | domain
12 | | vdc | vdc
13 | 12 | cloudstack | vdc.cloudstack
9 | 13 | ipv4 | vdc.cloudstack.ipv4
5 | 13 | virtualmachine | vdc.cloudstack.virtualmachine
8 | 13 | volume | vdc.cloudstack.volume
6 | 5 | cpu | vdc.cloudstack.virtualmachine.cpu
15 | 9 | rfc1918 | vdc.cloudstack.ipv4.rfc1918
17 | 9 | nononymous | vdc.cloudstack.ipv4.nononymous
16 | 9 | tolerant | vdc.cloudstack.ipv4.tolerant
14 | 9 | tier-a | vdc.cloudstack.ipv4.tier-a
7 | 5 | ram | vdc.cloudstack.virtualmachine.ram
(13 rows)
如何解决查询,导致结果中只有叶子? vdc.cloudstack.volume
行,没有vdc
,vdc.cloudstack
行
UPD
没有孩子的行
答案 0 :(得分:1)
排除表中其他位置deep_name
具有超字符串的行:
WITH RECURSIVE tree AS (...)
SELECT * FROM tree AS t1
WHERE NOT EXISTS (
SELECT 1 FROM tree AS t2
WHERE t2.deep_name
LIKE t1.deep_name || '.%'
);
答案 1 :(得分:0)
Laurenz Albe的回答给了我一个主意。我认为对孩子进行计数比使用琴弦更有效。
我的解决方法是:
WITH RECURSIVE tree AS (...)
SELECT * FROM tree t1
WHERE not EXISTS ( SELECT 1 FROM tree t2 WHERE t1.id = t2.parent_id );