recursive search
Date: Sat, 10 Sep 2016 01:01:03 +0200
Message-ID: <57d33f2f$0$24777$426a74cc_at_news.free.fr>
[Quoted] Hello folks,
I have a table of elements.
[Quoted] [Quoted] Each of these elements can be a parent of another element.
For example:
"ElementA" is:
- parent of "ElementB"
- parent of "ElementC"
"ElementB" has no chidren
"ElementC" is:
- parent of "ElementD"
- parent of "ElementA"
"ElementD" is:
- parent of "ElementE"
"ElementE" has no chidren
Etc.
You can notice that "ElementC" is parent of his parent "ElementA"(unlike
in real world).
So any element can be a parent of any other element (except directly
himself).
We have 2 tables, one which list all the elements (table "element"), and another for relationships (table "relation"):
create database test;
use test;
create table element(id int primary key, element varchar(8));
insert into element (id,element) values
(1,'ElementA'),(2,'ElementB'),(3,'ElementC'),(4,'ElementD'),(5,'ElementE');
create table relation (parent int, child int);
insert into relation (parent, child) values (1,2),(1,3),(3,4),(3,1),(4,5);
mysql> select * from element;
+----+----------+
| id | element |
+----+----------+
| 1 | ElementA | | 2 | ElementB | | 3 | ElementC | | 4 | ElementD | | 5 | ElementE |
+----+----------+
5 rows in set (0.00 sec)
mysql> select * from relation;
+--------+-------+
| parent | child |
+--------+-------+
| 1 | 2 | | 1 | 3 | | 3 | 4 | | 3 | 1 | | 4 | 5 |
+--------+-------+
5 rows in set (0.00 sec)
Maybe you already have an idea of the question!
For a given element, I'd like to get all the descendants (and descendants of descendants) of this element. 2 possibilities:
- Variant 1: Getting all descendants and descendants of descendants and treating all those descendants simply as "direct" descendants (no difference between children and grandchildren and ...) For "ElementA", the result would be: "ElementB" "ElementC" "ElementD" "ElementE"
- Variant 2: Getting all descendants and descendants of descendants and keeping relationships: For "ElementA", we would have: "ElementB" "ElementC" "ElementD" "ElementE"
Either way, I don't care to know if "ElementA" is parent (or grandparent...) of himself and we need to avoid an infinite loop.
I know how to manage this with an external tool (like PHP), multiple
mysql queries and recursion.
I could have a function like in:
function getChidren($element) { // Returns array of descendants // getChildren() builds an array with descendants and returns it // Query to the database to get all children of "$element". // In the first call of this function (for "elementA"), that // ...would return "ElementB" and "ElementC". // So we would then call: // getChildren("ElementB"); // getChildren("ElementC"); // and so on ... $ret = array( // to hold all descendants of "$element" $element => array() ); // Query database and get descendants $descendants = query_db_to_get_descendants($element); // Loop on all descendants and find their descendants foreach ($descendants as $descendant) { // Recursion, add descendants to the array $ret[$element][] = getChildren($descendant); // Add some logic to avoid infinite loop // Global variable (which would need a reset // ...before the first call of getChildren()) // Or some other way (add a parameter to getChildren() // ...with all found descendants up to now) // Or ... } return $ret;
}
This should return something like (for "ElementA"): array(
'ElementA' => array( 'ElementB' => array(), 'ElementC' => array( 'ElementD' => array( 'ElementE' => array() ) ) )
)
As you guessed, this is for variant 2.
For variant 1, the returned array would be: array(
'ElementB', 'ElementC', 'ElementD', 'ElementE'
)
Now the question:
[Quoted] [Quoted] Is there a way to achieve this just using sql ?
[Quoted] I hope I was clear and thanks for getting up to here, mireero Received on Sat Sep 10 2016 - 01:01:03 CEST