簡體   English   中英

使用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;

http://sqlfiddle.com/#!15/b5b4c/23

我認為您可以在沒有自我加入的情況下做到這一點。

您可以使用以下表達式選擇給定節點的所有后代: 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM