MySQL递归查找树形结构(这个方法太实用了!)
肥肥技术宅 人气:0这两天,遇到了重要节点的需求。这里简单做个总结。
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;
这样,就可以在查询语句中使用
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;
总结
加载全部内容