3

我一直在使用 Postgresltree构造来存储层次结构。现在,我想收集树中的所有叶子节点。有没有一个简单的机制来做到这一点?

CREATE TABLE foo
AS
  SELECT node::ltree
  FROM ( VALUES
    ('Top.Astronomy'),
    ('Top.Astronomy.Astrophysics'),
    ('Top.Pictures'),
    ('Top.Pictures.Stars')
  ) AS t(node);

我如何返回

Top.Astronomy.Astrophysics
Top.Pictures.Stars
4

2 回答 2

5

使用@>

一种方法是使用contains 运算符@>

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)
于 2017-04-20T06:58:13.353 回答
0

如果叶子总是在第三层,这样做:

SELECT * FROM foo WHERE node ~ '*{2}.*';

量词非常有用。您还可以在长分支的中间找到节点。要在https://www.postgresql.org/docs/current/static/ltree.html的文档中使用 PostgreSQL 示例测试表

SELECT * FROM test WHERE path ~ '*{2}.Astronomy.*{1}';

将仅匹配四长分支的第三个中的“天文学”。

您还可以将另一列作为标志来指示它是否是叶子。(顺便说一句,@<> 运算符需要 gist 索引,我发现它在大型数据集上明显变慢。我删除了它,只使用 btree ~ 运算符。我把它拿出来,它工作正常,只是不需要,我猜。)

于 2017-09-29T13:50:43.047 回答