He estado usando la construcciónltree de Postgres para almacenar una estructura jerárquica. Ahora, quiero recolectar todos los nodos de hojas en el árbol. ¿Hay un mecanismo directo para hacer esto?
CREATE TABLE foo AS SELECT node::ltree FROM ( VALUES ('Top.Astronomy'), ('Top.Astronomy.Astrophysics'), ('Top.Pictures'), ('Top.Pictures.Stars') ) AS t(node);como regreso
Top.Astronomy.Astrophysics Top.Pictures.Stars@> Una forma es usar el operador contiene @>
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)Si las hojas siempre están en el tercer nivel, haz esto:
SELECT * FROM foo WHERE node ~ '*{2}.*';Los cuantificadores son bastante útiles. También puede encontrar nodos en medio de una rama larga. Para usar la tabla de prueba de ejemplo de PostgreSQL en los documentos en https://www.postgresql.org/docs/current/static/ltree.html
SELECT * FROM test WHERE path ~ '*{2}.Astronomy.*{1}';coincidirá solo con la 'Astronomía' en la tercera parte de una rama de cuatro longitudes.
También podría tener otra columna como bandera para indicar si es una hoja o no. ( Por cierto, los operadores @<> requieren el índice esencial, y descubrí que es significativamente más lento en un conjunto de datos grande. Lo eliminé y solo usé el operador btree ~. Lo eliminé y funciona bien, solo que no es necesario, Supongo.)