I’m oversimplifying my problem a bit.
I have a table with the following format:
id | parent_id | name |
---|---|---|
1 | [null] | id1 |
2 | 1 | id2 |
3 | 2 | aa3 |
4 | 3 | bb4 |
5 | 2 | abc |
6 | [null] | abc1 |
I want to retrieve, in SQL ideally the path to root – (ie. node with parent_id = null)
For example:
getPath(5) -> "id1 / id2 / abc"
getPath(4) -> "id1 / id2 / aa3 / bb4"
getPath(6) -> "abc1"
I’ve already build a python function that constructs the path – while loop breaking when parent_id is null and inserting the name at the beginning of the string, but I’m hoping there’s a way of getting this solved with a single DB operation, as opposed to multiple selects.
Any pointers on where to find a solution?
Many thanks!
4
Answers
Depending on what you are trying to do you can no doubt improve this. Perhaps you want the path as an array for example.
Note that something very similar will work in most modern databases from sqlite3 to IBM db2 – consult your local documentation.
Something like:
Now let’s populate some values:
To query:
You will want indexes on
id
andparent_id
at the very least.You can do it using a
recursive
query withconcat
, by simply pass theid
in the extern where clause to get the pathDemo here
The query below is comprised of a function containing a recursive
cte
to generate the path. The function can then be called per your example to produce the path elsewhere in your script:Usage:
See fiddle
If you are retrieving the path for each id returned in another result set, it would make more sense to join directly to a recursive CTE which is seeded with the root node of the hierarchy.
When getting/building the path for a specific node it does not make sense to start at the root and build the entire tree. We should be starting with the specified node and walking up the tree:
Or wrapped in a function:
Usage:
Here is a db<>fiddle