当前位置:首页 > 编程教程 > mysql技术文章 > MySQL递归查询树状表的子节点、父节点具体实现

实现MySQL递归查询树状表的子节点、父节点具体方法

  • 发布时间:
  • 作者:码农之家
  • 点击:149

这篇文章主要知识点是关于MySQL、递归查询、树状表、子节点、父节点、Mysql树形递归查询的实现方法 的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子书

PHP与MySQL高性能应用开发
  • 类型:PHP开发大小:60.5 MB格式:PDF作者:杜江
立即下载

MySQL递归查询树状表的子节点、父节点具体实现

简介:mysql5.0.94版本,该版本以及较高级的版本(5.5、6等等)尚未支持循环递归查询,和sqlserver、oracle相比,mysql难于在树状表中层层遍历的子节点。本程序重点参考了下面的资料,写了两个sql存储过程,子节点查询算是照搬了,父节点查询是逆思维弄的。

表结构和表数据就不公示了,查询的表user_role,主键是id,每条记录有parentid字段(对应该记录的父节点,当然,一个父节点自然会有一个以上的子节点嘛)
 

CREATE FUNCTION `getChildList`(rootId INT)
RETURNS varchar(1000)
BEGIN
DECLARE sChildList VARCHAR(1000);
DECLARE sChildTemp VARCHAR(1000);
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 user_role where FIND_IN_SET(parentid,sChildTemp)>0;
END WHILE;
RETURN sChildList;
END;
/*获取子节点*/
/*调用: 1、select getChildList(0) id; 2、select * 5From user_role where FIND_IN_SET(id, getChildList(2));*/


CREATE FUNCTION `getParentList`(rootId INT)
RETURNS varchar(1000)
BEGIN
DECLARE sParentList varchar(1000);
DECLARE sParentTemp varchar(1000);
SET sParentTemp =cast(rootId as CHAR);
WHILE sParentTemp is not null DO
IF (sParentList is not null) THEN
SET sParentList = concat(sParentTemp,',',sParentList);
ELSE
SET sParentList = concat(sParentTemp);
END IF;
SELECT group_concat(parentid) INTO sParentTemp FROM user_role where FIND_IN_SET(id,sParentTemp)>0;
END WHILE;
RETURN sParentList;
END;
/*获取父节点*/
/*调用: 1、select getParentList(6) id; 2、select * From user_role where FIND_IN_SET(id, getParentList(2));*/

弄完了,pm说不要弄存储结构,在java里面多查几次吧。。。存储结构有很多优点,包括加快查询速度、提高安全性等等,但是会加大数据库负荷,很多文章建议结合使用,个人也觉得少用点会好些。

Mysql树形递归查询的实现方法

前言

对于数据库中的树形结构数据,如部门表,有时候,我们需要知道某部门的所有下属部分或者某部分的所有上级部门,这时候就需要用到mysql的递归查询

最近在做项目迁移,Oracle版本的迁到Mysql版本,遇到有些oracle的函数,mysql并没有,所以就只好想自定义函数或者找到替换函数的方法进行改造。

Oracle递归查询

oracle实现递归查询的话,就可以使用start with ... connect by

connect by递归查询基本语法是:

select 1 from 表格 start with ... connect by prior id = pId

start with:表示以什么为根节点,不加限制可以写1=1,要以id为123的节点为根节点,就写为start with id =123

connect by:connect by是必须的,start with有些情况是可以省略的,或者直接start with 1=1不加限制

prior:prior关键字可以放在等号的前面,也可以放在等号的后面,表示的意义是不一样的,比如 prior id = pid,就表示pid就是这条记录的根节点了

具体可以参考我以前写的一篇oracle方面的博客:https://www.jb51.net/article/156306.htm

Oracle方面的实现

<select id="listUnitInfo" resultType="com.admin.system.unit.model.UnitModel" databaseId="oracle">
 select distinct u.unit_code,
 u.unit_name,
 u.unit_tel,
 u.para_unit_code
 from lzcity_approve_unit_info u
 start with 1 = 1
 <if test="unitCode != null and unitCode !=''">
 and u.unit_code = #{unitCode}
 </if>
 <if test="unitName!=null and unitName!=''">
 and u.unit_name like '%'|| #{unitName} ||'%'
 </if>
 connect by prior u.unit_code = u.para_unit_code
 and u.unit_code <>u.para_unit_code
 </select>

Mysql递归查询

下面主要介绍Mysql方面的实现,Mysql并没有提供类似函数,所以只能通过自定义函数实现,网上很多这种资料,不过已经不知道那篇是原创了,这篇博客写的不错,https://www.jb51.net/database/201209/152513.html, 下面我也是用作者提供的方法实现自己的,先感谢作者的分享

这里借用作者提供的自定义函数,再加上Find_in_set函数 find_in_set(u.unit_code,getunitChildList(#{unitCode})) ,getunitChildList是自定义函数

<select id="listUnitInfo" resultType="com.admin.system.unit.model.UnitModel" databaseId="mysql">
 select distinct u.unit_code,
  u.unit_name,
  u.unit_tel,
  u.para_unit_code
  from t_unit_info u
  <where>
  <if test="unitCode != null and unitCode !=''">
  and find_in_set(u.unit_code,getunitChildList(#{unitCode}))
  </if>
  <if test="unitName!=null and unitName!=''">
  and u.unit_name like concat('%', #{unitName} ,'%')
  </if>
  </where>
 </select>

getUnitChildList自定义函数

DELIMITER $$

USE `gd_base`$$

DROP FUNCTION IF EXISTS `getUnitChildList`$$

CREATE DEFINER=`root`@`%` FUNCTION `getUnitChildList`(rootId INT) RETURNS VARCHAR(1000) CHARSET utf8
BEGIN
 DECLARE sChildList VARCHAR(1000);
 DECLARE sChildTemp VARCHAR(1000);
 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(unit_code) INTO sChildTemp FROM LZCITY_APPROVE_UNIT_INFO WHERE FIND_IN_SET(para_unit_code,sChildTemp)>0;
 END WHILE;
 RETURN sChildList;
END$$

DELIMITER ;

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对码农之家的支持。

以上就是本次给大家分享的关于java的全部知识点内容总结,大家还可以在下方相关文章里找到相关文章进一步学习,感谢大家的阅读和支持。

MySQL递归查询树状表的子节点、父节点 相关电子书
学习笔记
网友NO.273030

MySQL5.7.18修改密码的实例分享

MySQL 5.7.18中如何修改密码: 1.首先关闭MySQL服务器: 可以在任务管理器中直接关闭,也可以在cmd中关闭mysql :net stop mysql 2.打开安全模式,可以免密码登录:cmd中先跳转至安装目录下:d: cd D:\Mysql\mysql-5.7.18-winx64\bin 然后输入: mysqld --defaults-file=D:\Mysql\mysql-5.7.18-winx64\my.ini --console --skip-grant-tables (注意自己修改安装路径) 3.另开一个dos窗口输入 mysql -uroot -p ,然后无需输入密码直接enter键进入; 4.接下来先打开mysql 数据库:use mysql; 然后输入 update mysql.user set authentication_string=password(新密码) where user=root; 接着刷新权限:flush privileges; 接着退出:quit; 5.打开MYSQL服务器!!!可以手动打开,也可以在cmd中输入net start mysql 打开。 6.接下来就可以使用新密码登录了。 以上所述是小编给大家介绍的MySQL5.7.18修改密码的方法,希望对大家有所帮助,如果大家有任何疑……

网友NO.923037

MySQL存储过程中的基本函数和触发器的相关学习教程

MySQL存储过程的常用函数 一.字符串类 CHARSET(str) //返回字串字符集 CONCAT (string2 [,... ]) //连接字串 INSTR (string ,substring ) //返回substring首次在string中出现的位置,不存在返回0 LCASE (string2 ) //转换成小写 LEFT (string2 ,length ) //从string2中的左边起取length个字符 LENGTH (string ) //string长度 LOAD_FILE (file_name ) //从文件读取内容 LOCATE (substring , string [,start_position ] ) 同INSTR,但可指定开始位置 LPAD (string2 ,length ,pad ) //重复用pad加在string开头,直到字串长度为length LTRIM (string2 ) //去除前端空格 REPEAT (string2 ,count ) //重复count次 REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替换search_str RPAD (string2 ,length ,pad) //在str后用pad补充,直到长度为length RTRIM (string2 ) //去除后端空格 STRCMP (string1 ,string2 ) //逐字符比较两字串大小, SUBSTRING (str , position [,length ]) //从str的position开始,取length个字符, 注:……

网友NO.271903

十个实用且简单的MySQL函数

函数 0. 显示当前时间 命令:select now()。 作用: 显示当前时间。 应用场景: 创建时间,修改时间等默认值。 例子: mysql select now();+---------------------+| now() |+---------------------+| 2017-12-27 20:14:56 |+---------------------+1 row in set (0.00 sec) 1. 字符长度 命令:select char_length('andyqan')。 作用: 显示指定字符长度。 应用场景: 查看字符长度时。 例子: mysql select char_length('andyqian');+-------------------------+| char_length('andyqian') |+-------------------------+| 8 |+-------------------------+1 row in set (0.00 sec) 2. 日期格式化 命令:select date_format(now(),'%y-%m-%d)。 作用:格式化日期。 应用场景:格式化日期时。 例子: mysql select date_format(now(),'%y-%m-%d');+-------------------------------+| date_format(now(),'%y-%m-%d') |+-------------------------------+| 17-12-28 |+-------------------------------+1 row in set (0.00 sec) 这里支持的格式有: %y:表示……

网友NO.105823

mysql表的基础操作汇总(三)

针对mysql表进行的基础操作,具体内容如下 1.创建表: 创建表的语法形式: CREATE TABLE table_name( 属性名 数据类型, 属性名 数据类型, ... 属性名 数据类型) 示例: CREATE TABLE t_dept( deptno int, dname varchar(20), loc varchar(20) 备注:在创建表之前,通常你需要使用 USE 库名;这样一条语句来选择一个库,在所选择的库中创建表。对于表名标识符,不能是mysql的关键字,如 CREATE、USE等,建议表名标识符为t_xxx或者tab_xxx;各属性之间用逗号隔开,最后一个属性后不需要使用逗号。 2.查看表结构: 2.1 DESCRIBE语句查看表的定义 USE 库名; //选择一个库 DESCRIBE 表名; //查看表的定义信息,DESCRIBE可以使用DESC代替也可 2.2 SHOW CREATE TABLE 语句查看表的详细定义 USE 库名; //选择一个库 SHOW CREATE TABLE 表名 \G 表名; //查看表的定义信息 备注: 在显示表的详细定义信息时,可以使用”;” “……

网友NO.747644

mysql ndb集群备份数据库和还原数据库的方法

1、在管理节点上进行备份。 ndb_mgm start backup nowait ndb_mgm Node 3: Backup 4 started from node 1 Node 3: Backup 4 started from node 1 completed StartGCP: 43010 StopGCP: 43013 #Records: 2138 #LogRecords: 0 Data: 53068 bytes Log: 0 bytes ndb_mgm shutdown Node 3: Cluster shutdown initiated Node 4: Cluster shutdown initiated Node 4: Node shutdown completed. Node 3: Node shutdown completed. NDB Cluster node(s) have shutdown. Disconnecting to allow management server to shutdown. ndb_mgm exit 2、删掉SQL节点的数据。 DROP DATABASE TEST_CLUSTER; 、关闭MYSQLD服务器。 [root@localhost bin]# service mysqld stop Shutting down MySQL... SUCCESS! 3、重新顺序启动所有节点。 [root@localhost mysql]# /usr/local/mysql/ndb_mgmd -f /etc/config.ini [root@localhost data]# /usr/local/mysql/bin/ndbd --initial 我发现如果不带这个 --initial选项的话,恢复会失败。 [root@localhost bin]# service mysqld start Starting MySQL SUCCESS! 4、在NDBD节点上进行恢复……

<
1
>

Copyright 2018-2020 www.xz577.com 码农之家

版权投诉 / 书籍推广 / 赞助:520161757@qq.com