vpe*_*igo 8 postgresql hierarchy postgresql-9.4
我想问一个关于仅使用VIEWs将 PostgreSQL ltree 结构转换为仅具有一个查询的嵌套集结构的方法的问题。
例如,我有一个表,其中包含相互关联的数据,如下图所示:
所以,表声明是
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' |
Run Code Online (Sandbox Code Playgroud)
我必须将此表转换为这样的表:
KeywordSets(id INT PRIMARY KEY, value TEXT, lft INT, rgt INT);
Run Code Online (Sandbox Code Playgroud)
其中左右边框的规则是根据嵌套集规则完成的。我找到了如何在每个级别上获取顶点的方法
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 |
Run Code Online (Sandbox Code Playgroud)
但我不知道如何正确枚举它们(所以“A”左 = 1,右 = 16,“B”左 = 2,右 = 9 等等......)
如果我需要更清楚,请告诉我。
谁能给我一个想法怎么做?
我认为有一种不使用递归查询的方法可以解决这个问题:
WITH cte AS
( SELECT
m.*,
( SELECT COUNT(*)
FROM KeywordLtree AS d
WHERE m.path @> d.path
) AS descendants,
( SELECT COUNT(*)
FROM KeywordLtree AS a
WHERE a.path @> m.path
) AS ancestors,
ROW_NUMBER() OVER (ORDER BY m.path) AS rn
FROM KeywordLtree AS m
)
SELECT cte.*,
2 * rn - ancestors AS lft,
2 * rn - ancestors + 2 * descendants - 1 AS rgt
FROM cte
ORDER BY path ;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1362 次 |
| 最近记录: |