使用 Postgres ltree 收集所有叶节点
Collect all leaf nodes with Postgres ltree
我一直在使用 Postgres ltree
构造来存储层次结构。现在,我想收集树中的所有叶节点。有没有一个简单的机制来做到这一点?
CREATE TABLE foo
AS
SELECT node::ltree
FROM ( VALUES
('Top.Astronomy'),
('Top.Astronomy.Astrophysics'),
('Top.Pictures'),
('Top.Pictures.Stars')
) AS t(node);
我如何return
Top.Astronomy.Astrophysics
Top.Pictures.Stars
使用@>
一种方法是使用 contains operator @>
SELECT *
FROM foo AS f1
WHERE NOT EXISTS (
SELECT *
FROM foo AS f2
WHERE f1.node @> f2.node
AND f1.node <> f2.node
);
node
----------------------------
Top.Astronomy.Astrophysics
Top.Pictures.Stars
(2 rows)
如果叶子总是在第三层,这样做:
SELECT * FROM foo WHERE node ~ '*{2}.*';
量词非常有用。您还可以在长分支的中间找到节点。在 https://www.postgresql.org/docs/current/static/ltree.html
的文档中使用 PostgreSQL 示例测试 table
SELECT * FROM test WHERE path ~ '*{2}.Astronomy.*{1}';
将仅匹配四长度分支的第三个 'Astronomy'。
您还可以将另一列作为标志来指示它是否是叶子。 (顺便说一句,@<> 运算符需要 gist 索引,我发现它在大型数据集上速度明显较慢。我删除了它,只使用 btree ~ 运算符。 我把它拿出来了,它工作正常,只是不需要,我想。)
我一直在使用 Postgres ltree
构造来存储层次结构。现在,我想收集树中的所有叶节点。有没有一个简单的机制来做到这一点?
CREATE TABLE foo
AS
SELECT node::ltree
FROM ( VALUES
('Top.Astronomy'),
('Top.Astronomy.Astrophysics'),
('Top.Pictures'),
('Top.Pictures.Stars')
) AS t(node);
我如何return
Top.Astronomy.Astrophysics
Top.Pictures.Stars
使用@>
一种方法是使用 contains operator @>
SELECT *
FROM foo AS f1
WHERE NOT EXISTS (
SELECT *
FROM foo AS f2
WHERE f1.node @> f2.node
AND f1.node <> f2.node
);
node
----------------------------
Top.Astronomy.Astrophysics
Top.Pictures.Stars
(2 rows)
如果叶子总是在第三层,这样做:
SELECT * FROM foo WHERE node ~ '*{2}.*';
量词非常有用。您还可以在长分支的中间找到节点。在 https://www.postgresql.org/docs/current/static/ltree.html
的文档中使用 PostgreSQL 示例测试 tableSELECT * FROM test WHERE path ~ '*{2}.Astronomy.*{1}';
将仅匹配四长度分支的第三个 'Astronomy'。
您还可以将另一列作为标志来指示它是否是叶子。 (顺便说一句,@<> 运算符需要 gist 索引,我发现它在大型数据集上速度明显较慢。我删除了它,只使用 btree ~ 运算符。 我把它拿出来了,它工作正常,只是不需要,我想。)