第一篇文章,從某個同行問我的問題開始。
他的問題大概是這樣的:自己已經用Oracle的Start with...Connect By實現了樹的遞歸查詢,但是現在要求變了,要用MYSQL也實現相同的遞歸查詢樹的功能。這個功能是我從以前從未使用到過的,於是,我上網查詢、找了一些資料開始做了起來。我喜歡這種“自己每次在幫助了別人的同時又提高了自己”的進步,因爲,我始終相信,會分享、會幫助別人的人註定海納百川。到最後,功夫不多,總算給他提供瞭解決方案。我的解決方案只是針對同一個表,兩個表只需要在方法裏增加兩個表的連接條件即可。
下面是我的一些MYSQL最終代碼可供解決參考:
創建表nodelist:
- CREATE TABLE nodelist(
- id INT PRIMARY KEY, //本節點ID。
- nodename VARCHAR(20), //節點名稱,爲方便辨別而已。
- pid INT //父節點。
- );
插入表測試數據:
- Insert INTO nodelist VALUES(1,'A',null); //父節點爲,即根節點。
- Insert INTO nodelist VALUES(2,'B',1);
- Insert INTO nodelist VALUES(3,'C',1);
- Insert INTO nodelist VALUES(4,'D',2);
- Insert INTO nodelist VALUES(5,'E',3);
- Insert INTO nodelist VALUES(6,'F',3);
- Insert INTO nodelist VALUES(7,'G',5);
- Insert INTO nodelist VALUES(8,'H',7);
- Insert INTO nodelist VALUES(9,'I',8);
- Insert INTO nodelist VALUES(10,'J',8);
創建函數getChildList():
- CREATE FUNCTION `getChildList`(rootId INT) //rootId爲你要查詢的節點。
- RETURNS VARCHAR(1000)
- BEGIN
- DECLARE pTemp VARCHAR(1000);
- DECLARE cTemp VARCHAR(1000); //兩個臨時變量
- SET pTemp = '$';
- SET cTemp =cast(rootId as CHAR); //把rootId強制轉換爲字符。
- WHILE cTemp is not null DO
- SET pTemp = concat(pTemp,',',cTemp); //把所有節點連接成字符串。
- SELECT group_concat(id) INTO cTemp FROM nodelist
- WHERE FIND_IN_SET(pid,cTemp)>0;
- // FIND_IN_SET(str,strlist)的方法網上大把不解釋。
- END WHILE;
- RETURN pTemp;
- END
執行方法getChildList(1):
- SELECT getChildList(1);
運行結果如下圖:
查詢節點爲“3”下的所有節點:
- SELECT * FROM nodelist WHERE FIND_IN_SET(id, getChildList(3));
運行結果如下圖: