MySQL實現遞迴查詢樹形結構
阿新 • • 發佈:2018-12-12
這兩天,遇到了子節點的需求.這裡簡單做個總結.
1.資料庫中的樹形結構
資料庫中存貯的資料,以ID和P_ID(父id),來存貯樹形結構
這樣如果需要查詢某個節點的子節點,就可以尋找P_ID.如果要查詢所有子節點,就需要遍歷所有的子節點的子節點.
如果要判斷是否為同級的節點,就可以查詢是否有相同的父節點.
2.MySQL中如何查詢相應的資料
這裡,我採用的是寫一個存貯函式.在查詢時可以直接使用.當然,為了以後查詢方便,也可在一個檢視使用.
3.準備工作
資料庫表,為了方便,只有三個欄位,能夠說明情況即可.
CREATE TABLE `city` ( `i_id` int(11) NOT NULL AUTO_INCREMENT , `p_id` int(11) NULL DEFAULT NULL , `c_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , PRIMARY KEY (`i_id`) ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci AUTO_INCREMENT=11 ROW_FORMAT=COMPACT;
隨便插入幾條資料
實現介紹倆個關鍵的函式
group_concat(column_name): 多條記錄合成一條記錄
SELECT GROUP_CONCAT(i_id)
FROM city
WHERE p_id='2'
find_in_set(column_name, strlist)在多條記錄中查詢特定列
SELECT * FROM city
WHERE FIND_IN_SET(p_id,'1,4')
4.具體的實現(由淺入深)
1.只查具體一級下級
SELECT GROUP_CONCAT(i_id) AS ids FROM city WHERE p_id=1;
2.查詢某一個節點的子節點
在存貯函式之前,要注意一點.雖然引數名是 param_i_id,但查詢時 要讓p_id=param_i_id
CREATE DEFINER = `root`@`localhost` FUNCTION `getSubNodes`(param_i_id int) RETURNS varchar(100) BEGIN #輸入I_ID 輸出此I_ID下的所有子節點(只有一級) DECLARE strSubIds VARCHAR(100); DECLARE strPid VARCHAR(100); SET strSubIds = '$'; SET strPid =cast(param_i_id as CHAR); SELECT GROUP_CONCAT(i_id) INTO strSubIds FROM city WHERE p_id=strPid; RETURN strSubIds; END;
這樣,可以就可以在查詢語句中使用
(上面的1.去不掉,富文字好煩)
3.查詢所有下級
查到了一級,只要迴圈查詢到某一個節點(這個節點沒有子節點),就結束
CREATE DEFINER = `root`@`localhost` FUNCTION `getAllSubNodes`(`param_i_id` int)
RETURNS varchar(100)
BEGIN
DECLARE strAllSubIds VARCHAR(100);
DECLARE strTempPid VARCHAR(100);
#先得到第一級,也可以掉用getSubNodes(param_i_id);
# SELECT GROUP_CONCAT(i_id) INTO strAllSubIds FROM city WHERE p_id=param_i_id;
SET strAllSubIds = getSubNodes(param_i_id);
SET strTempPid = strAllSubIds;
#根據 strTempPid 判斷是否還有子節點
WHILE strTempPid is not null DO
SELECT group_concat(i_id) INTO strTempPid FROM city WHERE FIND_IN_SET(p_id,strTempPid)>0;
#需要對strTempPid判斷,非空用 , 連線
IF (strTempPid is not NULL) THEN
SET strAllSubIds = concat(strAllSubIds,',',strTempPid);
END IF;
END WHILE;
RETURN strAllSubIds;
END;
參考 : https://blog.csdn.net/bob_baobao/article/details/78104504