I have a table which I do a self-join. My sample table looks like this
-- Table genealogy
+--------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+-------+
| parent | int(11) | NO | PRI | NULL | |
| child | int(11) | NO | PRI | NULL | |
+--------+---------+------+-----+---------+-------+
2 rows in set (0.01 sec)
The concept goes like this (get ready for this one):
- To find the child of user parent=1, I look at the first level of user parent=1.
- To find the grandchild of user parent=1, I look for the child who is the child of the child of user parent=1.
- To get the great-grandchild (3rd level), I look for the child who is the child who is the child of the child of parent=1.
- …and so forth
It can get a little confusing but my query works just fine. I was wondering if there’s a much faster/optimized way of doing it since I’m only repeating my sql all over the place.
-- Get Child
SELECT parent, child AS '1st Level' FROM genealogy WHERE parent=1;
-- Get Grandchild
SELECT a.parent, b.child AS '2nd Level' FROM (SELECT * FROM genealogy WHERE parent=1) a INNER JOIN genealogy b ON a.child=b.parent;
-- Get Great-Grandchild
SELECT a.parent, b.child AS '3rd Level' FROM (SELECT a.parent, b.child FROM (SELECT * FROM genealogy WHERE parent=1) a INNER JOIN genealogy b ON a.child=b.parent) a INNER JOIN genealogy b ON a.child=b.parent;
-- And the list goes on
You could use another tree structure (called nested set):
This would enable you to select ALL childs (and grand childs and grand-grand-childs and so on) of a node inside the tree.
For example to select all children of genealogy id 1:
You may have a look at this for more information and more examples: http://www.ibase.ru/devinfo/DBMSTrees/sqltrees.html