I have a table in a relational database, in which I encode a tree using the technique known as Materialized path (also known as Lineage column). That is, for each node in my tree I have a row in the table, and for each row I have a string column named ancestry
where I store the path from the root node to the node represented by this row.
Is it possible, and if yes - how, to select the rows in the table orderd by preorder, that is they should appear in the result set in the order that would result by visiting the tree depth-first. I use MySQL - so no recursive queries and no ltree extension.
For example, a tree, it's table, and selected ordered by preorder:
1 SELECT * FROM nodes SELECT * FROM nodes ORDER BY ?depth_first_visit_order?
| \ id | ancestry id | ancestry
2 3 ------------- -------------
| | \ 1 | NULL 1 | NULL NOTE: I don't care about the
4 5 6 2 | 1 2 | 1 order of siblings!
| 3 | 1 4 | 1/2
7 4 | 1/2 3 | 1
5 | 1/3 5 | 1/3
6 | 1/3 7 | 1/3/5
7 | 1/3/5 6 | 1/3
Note: I am interested explicitly in doing this over a materialized path encoding!
Related: What are the options for storing hierarchical data in a relational database?
I believe what you want is an alphabetic sort.
SELECT id, ancestry, ancestry + '/' + CAST(id as nvarchar(10)) AS PathEnumeration
FROM nodes
ORDER BY 3 ASC;
I don't really remember how MySQL concatenates, but I'm sure my meaning is clear.
1
1/2
1/2/4
1/3
1/3/5
1/3/5/7
1/3/6
Note that it is an alphabetic sort, so 11 will show up before 2. But, you said you didn't care about sibling ordering. I, of course, would rewrite it as a nested set ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With