![](/img/trans.png)
[英]How to select all the hierarchy of a table with levels in PostgreSQL
[英]Selecting certain levels of a hierarchy with PostgreSQL
我有一個表,它使用枚舉路徑表示層次結構:
id | name | path
-----+-------+-------
1 | Bob | 1
2 | Joe | 2
3 | Kyle | 2/3
4 | Sarah | 2/4
5 | Jim | 5
6 | Steve | 5/6
7 | Adam | 5/7
8 | Frank | 5/7/8
9 | Sue | 5/7/9
我需要一個查詢,該查詢返回給定記錄的直接子記錄,並為每個子記錄返回其下所有子記錄的計數。
例如,針對Jim(id = 5)的查詢應返回以下集合:
id | name | path | subrecords
-----+-------+-------+------------
6 | Steve | 5/6 | 0
7 | Adam | 5/7 | 2
如果我做:
select did, name, path, SUBSTRING(path FROM '5\/[^\/]*$') as child_path from items where path ~ '5\/.*';
我參與其中...
did | name | path | child_path
-----+-------+-------+---------
6 | Steve | 5/6 | 5/6
7 | Adam | 5/7 | 5/7
8 | Frank | 5/7/8 |
9 | Sue | 5/7/9 |
...但是記錄8和9需要匯總為7以下的計數。
我試過了:
select SUBSTRING(path FROM '5\/[^\/]*$') as child_path, COUNT(id) as count from items where path ~ '5\/.*' GROUP BY child_path;
這讓我:
child_path | count
----------+-------
| 2
5/7 | 1
5/6 | 1
不。
我怎樣才能做到這一點?
在我看來,這可以完成工作。
SELECT i.id,
i.name,
i.path,
count(ii.id) AS cnt
FROM items i
LEFT OUTER JOIN items ii
ON ii.id != i.id AND ii.path LIKE i.path || '%'
WHERE i.path ~ '5\/[^\/]*$'
GROUP BY i.id,
i.name,
i.path;
我認為您可以在沒有自我加入的情況下做到這一點。
您可以使用以下表達式選擇給定節點的所有后代: path like '5' || '/' || id || '%'
path like '5' || '/' || id || '%'
path like '5' || '/' || id || '%'
。 然后,您可以通過選擇最多5個子字符串和下一個ID來匯總它們:
select left(path, length('5'||'/') + position('/' in split_part(path||'/', '5'||'/', 2)) - 1) as child,
count(*) - 1 as numdescendants
from items
where path like '5' || '/' || '%'
group by child;
count(*)
計算特定子代(包括該子代count(*)
的后代數量。 因此, - 1
獲取其后代的數量。
這應該可以工作,因此您可以用任何路徑替換'5'
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.