I got a following table:
col1 | col2 | col3
-----+------+-------
1 | a | 5
5 | d | 3
3 | k | 7
6 | o | 2
2 | 0 | 8
If a user searches for "1", the program will look at the col1
that has "1" then it will get a value in col3
"5", then the program will continue to search for "5" in col1
and it will get "3" in col3
, and so on. So it will print out:
1 | a | 5
5 | d | 3
3 | k | 7
If a user search for "6", it will print out:
6 | o | 2
2 | 0 | 8
How to build a SELECT
query to do that?
leftclickben's answer worked for me, but I wanted a path from a given node back up the tree to the root, and these seemed to be going the other way, down the tree. So, I had to flip some of the fields around and renamed for clarity, and this works for me, in case this is what anyone else wants too--
and
gives:
The accepted answer by @Meherzad only works if the data is in a particular order. It happens to work with the data from the OP question. In my case, I had to modify it to work with my data.
Note This only works when every record's "id" (col1 in the question) has a value GREATER THAN that record's "parent id" (col3 in the question). This is often the case, because normally the parent will need to be created first. However if your application allows changes to the hierarchy, where an item may be re-parented somewhere else, then you cannot rely on this.
This is my query in case it helps someone; note it does not work with the given question because the data does not follow the required structure described above.
The difference is that
table1
is being ordered bycol1
so that the parent will be after it (since the parent'scol1
value is lower than the child's).If you want to be able to have a SELECT without problems of the parent id having to be lower than child id, a function could be used. It supports also multiple children (as a tree should do) and the tree can have multiple heads. It also ensure to break if a loop exists in the data.
I wanted to use dynamic SQL to be able to pass the table/columns names, but functions in MySQL don't support this.
Here, the table
test
has to be modified to the real table name and the columns (ParentId,Id) may have to be adjusted for your real names.Usage :
Result :
SQL for test creation :
EDIT : Here is a fiddle to test it yourself. It forced me to change the delimiter using the predefined one, but it works.
Edit
Solution mentioned by @leftclickben is also effective. We can also use a stored procedure for the same.
We are using temp table to store results of the output and as the temp tables are session based we wont there will be not be any issue regarding output data being incorrect.
SQL FIDDLE Demo
Try this query:SQL FIDDLE Demo
:Stored procedure is the best way to do it. Because Meherzad's solution would work only if the data follows the same order.
If we have a table structure like this
It wont work.
SQL Fiddle Demo
Here is a sample procedure code to achieve the same.
Building off of Master DJon
Here is simplified function which provides the added utility of returning depth (in case you want to use logic to include the parent task or search at a specific depth)
Usage: