本文實例講述了MySQL實現(xiàn)樹狀所有子節(jié)點查詢的方法。,具體如下:
在Oracle 中我們知道有一個 Hierarchical Queries 通過CONNECT BY 我們可以方便的查了所有當前節(jié)點下的所有子節(jié)點。但很遺憾,在MySQL的目前版本中還沒有對應的功能。
在MySQL中如果是有限的層次,比如我們事先如果可以確定這個樹的最大深度是4, 那么所有節(jié)點為根的樹的深度均不會超過4,則我們可以直接通過left join 來實現(xiàn)。
但很多時候我們無法控制樹的深度。這時就需要在MySQL中用存儲過程來實現(xiàn)或在你的程序中來實現(xiàn)這個遞歸。本文討論一下幾種實現(xiàn)的方法。
樣例數(shù)據(jù):
| mysql> create table treeNodes -> ( -> id int primary key, -> nodename varchar(20), -> pid int -> );Query OK, 0 rows affected (0.09 sec)mysql> select * from treenodes;+----+----------+------+| id | nodename | pid |+----+----------+------+| 1 | A | 0 || 2 | B | 1 || 3 | C | 1 || 4 | D | 2 || 5 | E | 2 || 6 | F | 3 || 7 | G | 6 || 8 | H | 0 || 9 | I | 8 || 10 | J | 8 || 11 | K | 8 || 12 | L | 9 || 13 | M | 9 || 14 | N | 12 || 15 | O | 12 || 16 | P | 15 || 17 | Q | 15 |+----+----------+------+17 rows in set (0.00 sec) | 
樹形圖如下
| 1:A +-- 2:B | +-- 4:D | +-- 5:E +-- 3:C +-- 6:F +-- 7:G 8:H +-- 9:I | +-- 12:L | | +--14:N | | +--15:O | | +--16:P | | +--17:Q | +-- 13:M +-- 10:J +-- 11:K | 
方法一:利用函數(shù)來得到所有子節(jié)點號。
創(chuàng)建一個function getChildLst, 得到一個由所有子節(jié)點號組成的字符串.
| mysql> delimiter //mysql>mysql> CREATE FUNCTION `getChildLst`(rootId INT) -> RETURNS varchar(1000) -> BEGIN -> DECLARE sTemp VARCHAR(1000); -> DECLARE sTempChd VARCHAR(1000); -> -> SET sTemp = '$'; -> SET sTempChd =cast(rootId as CHAR); -> -> WHILE sTempChd is not null DO -> SET sTemp = concat(sTemp,',',sTempChd); -> SELECT group_concat(id) INTO sTempChd FROM treeNodes where FIND_IN_SET(pid,sTempChd)>0; -> END WHILE; -> RETURN sTemp; -> END -> //Query OK, 0 rows affected (0.00 sec)mysql>mysql> delimiter ; | 
使用我們直接利用find_in_set函數(shù)配合這個getChildlst來查找
| mysql> select getChildLst(1);+-----------------+| getChildLst(1) |+-----------------+| $,1,2,3,4,5,6,7 |+-----------------+1 row in set (0.00 sec)mysql> select * from treeNodes -> where FIND_IN_SET(id, getChildLst(1));+----+----------+------+| id | nodename | pid |+----+----------+------+| 1 | A | 0 || 2 | B | 1 || 3 | C | 1 || 4 | D | 2 || 5 | E | 2 || 6 | F | 3 || 7 | G | 6 |+----+----------+------+7 rows in set (0.01 sec)mysql> select * from treeNodes -> where FIND_IN_SET(id, getChildLst(3));+----+----------+------+| id | nodename | pid |+----+----------+------+| 3 | C | 1 || 6 | F | 3 || 7 | G | 6 |+----+----------+------+3 rows in set (0.01 sec) |