我想问一个关于将PostgreSQL ltree结构转换为仅使用VIEW
只进行一次查询的嵌套集结构的方法的问题。
例如,我有一张表格,其中包含彼此相关的数据,如下图所示:
所以,表格是
KeywordLtree(id INT PRIMARY KEY, value TEXT, path ltree);
-- And the data is:
pk | value | path |
0 | 'A' | '' |
0 | 'B' | '1' |
0 | 'C' | '2' |
0 | 'D' | '1.3' |
0 | 'E' | '1.4' |
0 | 'F' | '1.5' |
0 | 'G' | '2.6' |
0 | 'H' | '2.7' |
我必须将此表转换为此表:
KeywordSets(id INT PRIMARY KEY, value TEXT, lft INT, rgt INT);
根据嵌套集规则完成左边框和右边框的规则。 我找到了如何在每个级别获取顶点的方法
CREATE OR REPLACE RECURSIVE VIEW bfs (id, value, path, num_on_level, level) AS
SELECT id, value, path, row_number() OVER (), 0 as level
FROM KeywordLtreeSandbox WHERE path ~ '*{0}'
UNION ALL
SELECT C.id, C.value, C.path, row_number() OVER (PARTITION BY P.path), level + 1
FROM KeywordLtreeSandbox C JOIN bfs P ON P.path @> C.path
WHERE nlevel(C.path) = level + 1;
-- Data would be like below
id | value | path | num_on_level | level |
0 | "A" | "" | 1 | 0 |
1 | "B" | "1" | 1 | 1 |
2 | "C" | "2" | 2 | 1 |
3 | "D" |"1.3" | 1 | 2 |
4 | "E" |"1.4" | 2 | 2 |
5 | "F" |"1.5" | 3 | 2 |
6 | "G" |"2.6" | 1 | 2 |
7 | "H" |"2.7" | 2 | 2 |
但我不知道如何正确枚举它们(所以“A”左= 1,右= 16,“B”左= 2,右= 9等等......)
如果我需要更清楚,请告诉我。
有人能告诉我这是怎么做的吗?
答案 0 :(得分:1)
当然是在stepic.org; - )
WITH RECURSIVE bfs(id, value, path, level, cnt) AS
(SELECT id, value, path, 0 as level,1 as cnt
FROM kts WHERE path ~ '*{0}'
UNION ALL
SELECT C.id, C.value, C.path, level + 1, 1 as cnt
FROM kts C JOIN bfs P ON P.path @> C.path
WHERE nlevel(C.path) = level + 1),
qsubtrees AS (SELECT K2.path AS p, COUNT(*) AS size FROM kts K LEFT JOIN kts K2 ON K.path <@ K2.path
GROUP BY K2.path),
result AS (SELECT id, value, path, level,
2*(SUM(cnt) OVER (ROWS UNBOUNDED PRECEDING))-1-level AS leftn, size
FROM bfs JOIN qsubtrees ON bfs.path=qsubtrees.p ORDER BY path)
SELECT '#', id, value, leftn, leftn+2*size-1 AS rightn FROM result ORDER BY leftn;