I have the following query and I'm using the postgres plugin ltree. I am trying to do something conceptually similar to cutting the tree along what you could imagine is the y-axis of the tree.
I can easily do this with the following query:
testdb2=# SELECT * FROM test WHERE yaxis >= 3 ORDER BY yaxis;
path | yaxis | leaf
--------------------------------+-------+------
Top.Hobbies.Amateurs_Astronomy | 3 | t
Top.Science.Astronomy | 3 |
Top.Collections.Pictures | 3 |
Top.Hobbies | 4 |
Top.Science | 4 |
Top.Collections | 4 |
Top | 5 |
However I would like a tree query that does not return Top, Top.Hobbies, and Top.Science because there are nodes beneath these. I understand saying yaxis=3 would accomplish this but this set of data is a over simplification.
An important point is that these are not leaves. There is structure beneath. So I'm not looking for something that returns leaves.
This is the full set:
path | yaxis | leaf
-----------------------------------------------+-------+------
Top | 5 |
Top.Science | 4 |
Top.Science.Astronomy | 3 |
Top.Hobbies | 4 |
Top.Collections | 4 |
Top.Collections.Pictures.Astronomy | 2 |
Top.Collections.Pictures | 3 |
Top.Collections.Pictures.Astronomy.Stars | 1 | t
Top.Collections.Pictures.Astronomy.Galaxies | 1 | t
Top.Collections.Pictures.Astronomy.Astronauts | 1 | t
Top.Hobbies.Amateurs_Astronomy | 3 | t
Top.Science.Astronomy.Astrophysics | 2 | t
Top.Science.Astronomy.Cosmology | 2 | t
The values I would like to see are these:
path | yaxis | leaf
--------------------------------+-------+------
Top.Hobbies.Amateurs_Astronomy | 3 | t
Top.Science.Astronomy | 3 |
Top.Collections.Pictures | 3 |
But, again, not using the value 3 exact match, because this demo data is an over simplification.
Having the result of your first query, just find leaves in it:
with data(path) as (
-- select path from test where yaxis >= 3
values
('Top.Hobbies.Amateurs_Astronomy'::ltree),
('Top.Science.Astronomy'),
('Top.Collections.Pictures'),
('Top.Hobbies'),
('Top.Science'),
('Top.Collections'),
('Top')
)
select *
from data d1
where not exists (
select 1
from data d2
where d1.path <> d2.path
and d1.path @> d2.path);
path
--------------------------------
Top.Hobbies.Amateurs_Astronomy
Top.Science.Astronomy
Top.Collections.Pictures
(3 rows)