利用函数来得到所有子节点号 利用函数来取得最高级的节点号
在Oracle 中我們知道有一個 Hierarchical Queries 通過CONNECT BY 我們可以方便的查了所有當前節點下的所有子節點。但很遺憾,在MySQL的目前版本中還沒有對應的功能。?
在MySQL中如果是有限的層次,比如我們事先如果可以確定這個樹的最大深度是4, 那么所有節點為根的樹的深度均不會超過4,則我們可以直接通過left join 來實現。?
但很多時候我們無法控制樹的深度。這時就需要在MySQL中用存儲過程來實現或在你的程序中來實現這個遞歸。本文討論一下幾種實現的方法。?
樣例數據:
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???
方法一:利用函數來得到所有子節點號。?
創建一個function getChildLst, 得到一個由所有子節點號組成的字符串.??
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函數配合這個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)?
優點:?簡單,方便,沒有遞歸調用層次深度的限制 (max_sp_recursion_depth,最大255) ;?
缺點:長度受限,雖然可以擴大 RETURNS varchar(1000),但總是有最大限制的。?
MySQL目前版本( 5.1.33-community)中還不支持function 的遞歸調用。
?
總結
以上是生活随笔為你收集整理的利用函数来得到所有子节点号 利用函数来取得最高级的节点号的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 利用Traefik+Docker构建可弹
- 下一篇: Linux驱动技术(三) _DMA编程