MySQL遞歸查找樹形結(jié)構(gòu)(這個(gè)方法太實(shí)用了!)
這兩天,遇到了重要節(jié)點(diǎn)的需求。這里簡單做個(gè)總結(jié)。
1、數(shù)據(jù)庫中的樹形結(jié)構(gòu)
數(shù)據(jù)庫中存貯的數(shù)據(jù),以ID和P_ID(父id),來存貯樹形結(jié)構(gòu)
這樣如果需要查找某個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn),就可以尋找P_ID。如果要查找所有子節(jié)點(diǎn),就需要遍歷所有的子節(jié)點(diǎn)的子節(jié)點(diǎn)。
如果要判斷是否為同級(jí)的節(jié)點(diǎn),就可以查找是否有相同的節(jié)點(diǎn)。
2、MySQL中如何查找相應(yīng)的數(shù)據(jù)
這里,我采用的是一個(gè)存儲(chǔ)函數(shù)。在查詢時(shí)可以直接使用。當(dāng)然,為了以后查詢方便,也可以在一個(gè)視圖使用。
3、準(zhǔn)備工作
數(shù)據(jù)庫表,為了方便,只有三個(gè)字段,能夠說明情況即可。
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;
隨便插入幾條數(shù)據(jù)
實(shí)現(xiàn)介紹兩個(gè)關(guān)鍵的函數(shù)
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.具體的實(shí)現(xiàn)(由淺入深)
1.只查具體一級(jí)下級(jí)
SELECT GROUP_CONCAT(i_id) AS ids FROM city WHERE p_id=1;
2.查詢某一個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)
在存貯函數(shù)之前,要注意一點(diǎn)。雖然參數(shù)名是 param_i_id,但查詢時(shí) 要讓p_id=param_i_id
CREATE DEFINER = `root`@`localhost` FUNCTION `getSubNodes`(param_i_id int) RETURNS varchar(100) BEGIN #輸入I_ID 輸出此I_ID下的所有子節(jié)點(diǎn)(只有一級(jí)) 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;
這樣,就可以在查詢語句中使用
3.查詢所有下級(jí)
查到了一級(jí),只要循環(huán)查詢到某一個(gè)節(jié)點(diǎn)(這個(gè)節(jié)點(diǎn)沒有子節(jié)點(diǎn)),就結(jié)束
CREATE DEFINER = `root`@`localhost` FUNCTION `getAllSubNodes`(`param_i_id` int) RETURNS varchar(100) BEGIN DECLARE strAllSubIds VARCHAR(100); DECLARE strTempPid VARCHAR(100); #先得到第一級(jí),也可以掉用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; #根據(jù) strTempPid 判斷是否還有子節(jié)點(diǎn) WHILE strTempPid is not null DO SELECT group_concat(i_id) INTO strTempPid FROM city WHERE FIND_IN_SET(p_id,strTempPid)>0; #需要對(duì)strTempPid判斷,非空用 , 連接 IF (strTempPid is not NULL) THEN SET strAllSubIds = concat(strAllSubIds,',',strTempPid); END IF; END WHILE; RETURN strAllSubIds; END;
總結(jié)
到此這篇關(guān)于MySQL遞歸查找樹形結(jié)構(gòu)的文章就介紹到這了,更多相關(guān)MySQL遞歸查找樹形結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql下的max_allowed_packet參數(shù)設(shè)置詳解
本文主要介紹了mysql下的max_allowed_packet參數(shù)設(shè)置詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02mysql存儲(chǔ)過程之循環(huán)語句(WHILE,REPEAT和LOOP)用法分析
這篇文章主要介紹了mysql存儲(chǔ)過程之循環(huán)語句(WHILE,REPEAT和LOOP)用法,結(jié)合實(shí)例形式分析了mysql存儲(chǔ)過程循環(huán)語句WHILE,REPEAT和LOOP的原理、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-12-12MySQL count(1)、count(*)、count(字段)的區(qū)別
COUNT在數(shù)據(jù)庫行數(shù)統(tǒng)計(jì)中被廣泛使用,那么你知道MySQL count(1)、count(*)、count(字段)的區(qū)別嗎,本文就想的介紹一下,感興趣的可以了解一下2021-12-12mysql 設(shè)置自動(dòng)創(chuàng)建時(shí)間及修改時(shí)間的方法示例
這篇文章主要介紹了mysql 設(shè)置自動(dòng)創(chuàng)建時(shí)間及修改時(shí)間的方法,結(jié)合實(shí)例形式分析了mysql針對(duì)創(chuàng)建時(shí)間及修改時(shí)間相關(guān)操作技巧,需要的朋友可以參考下2019-09-09MySQL與PHP的基礎(chǔ)與應(yīng)用專題之自連接
MySQL是一個(gè)關(guān)系型數(shù)據(jù)庫管理系統(tǒng),由瑞典MySQL AB 公司開發(fā),屬于 Oracle 旗下產(chǎn)品。MySQL 是最流行的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)之一,本系列將帶你掌握php與mysql的基礎(chǔ)應(yīng)用,本篇從自連接開始2022-02-02MySQL針對(duì)Discuz論壇程序的基本優(yōu)化教程
這篇文章主要介紹了MySQL針對(duì)Discuz論壇程序的基本優(yōu)化教程,包括在緩存和索引等方面的優(yōu)化方法,需要的朋友可以參考下2015-11-11傻瓜式用Eclipse連接MySQL數(shù)據(jù)庫
本來不想寫這么簡單人文章,在百度上搜索我這個(gè)標(biāo)題,完全符合標(biāo)題的一大堆。但我按照那些文章?lián)v鼓了很久,就是不行。2015-09-09