通過父ID查詢下級ID很常見,本人遇到后做一個記錄
1,第一種方法是只能查詢到該ID的下一級,不包含父ID,而且只能查詢到一級
SELECT id FROM ( SELECT t1.*, IF(FIND_IN_SET(parent_id, @pids) > 0, @pids := CONCAT(@pids, ',', id), 0) AS ischild FROM ( SELECT * FROM sys_depart t WHERE t.status = '1' and t.del_flag='0' ORDER BY parent_id, id ) t1 , (SELECT @pids := #{pId}) t2 ) t3 WHERE t3.ischild != 0
2,第二種方法采用遞歸方法,先寫一個遞歸函數,在數據庫中,然后調用該函數即可
遞歸函數如下:特別注意我采用了 LONGTEXT 而不是 VARCHAR(4000),因為數據太大了,不夠存,會提示 data too long for column 'xxx' at row 1
CREATE DEFINER=`root`@`localhost` FUNCTION `getDepartChildListById`(rootId INT) RETURNS longtext CHARSET utf8mb3 BEGIN DECLARE sChildList LONGTEXT; DECLARE sChildTemp LONGTEXT; SET sChildTemp =CAST(rootId AS CHAR); WHILE sChildTemp IS NOT NULL DO IF (sChildList IS NOT NULL) THEN SET sChildList = CONCAT(sChildList,',',sChildTemp); ELSE SET sChildList = CONCAT(sChildTemp); END IF; SELECT GROUP_CONCAT(id) INTO sChildTemp FROM sys_depart WHERE FIND_IN_SET(parent_id,sChildTemp)>0; END WHILE; RETURN sChildList; END
CREATE DEFINER=`root`@`%` FUNCTION `getDepartChildList`(rootId VARCHAR(8)) RETURNS longtext CHARSET utf8mb4 READS SQL DATA BEGIN #開始 DECLARE sTemp longtext; #定義全局變量,查詢出來的id進行拼接 DECLARE sTempChd longtext; #臨時變量,用於循環查詢的單次接收 SET sTempChd =CAST(rootId AS CHAR); #賦值,進行查詢你 #SET sTempChd =rootId ; #賦值,進行查詢你 WHILE sTempChd IS NOT NULL DO #此處為循環 為null結束循環 IF (sTemp IS NOT NULL) THEN SET sTemp = CONCAT(sTemp,',',sTempChd); #將查詢的所有子節點賦值為全局 ELSE SET sTemp = CONCAT(sTempChd); END IF; #GROUP_CONCAT(id) : 將查詢出來的結果用逗號連接在一起 #使用find_in_set函數一次返回多條記錄 #id 是一個表的字段 然后每條記錄分別是id等於1,2,3,4,5的時候 #有點類似in (集合) SELECT GROUP_CONCAT(id) INTO sTempChd FROM sys_depart WHERE FIND_IN_SET(parent_id,sTempChd); #將查詢出來的子id, 再次將子id當作父id進行查詢 END WHILE; RETURN sTemp; #將最后結果返回出去 END
然后調用該函數即可查詢
select getDepartChildListById(#{pId}) from dual
以上是我的總結,沒有做詳細的說明,但是我想如果你遇到此類問題后,看一下應該能明白如果做
附表是關於數據類型比較