MYSQL 递归树查询的实现

本贴最后更新于 2442 天前,其中的信息可能已经时移世易

​    在 oracle 中我们可以使用 connect by prior 函数来实现组织树表递归的查询,但是在 mysql 中却没有该方法,为了能够使用该方法我们就得自己创建函数来实现该组织树的递归查询。以下实现了 2 种方式来满足子节点的递归查询与父节点的递归查询。

实现子递归查询

1.单个子递归查询的实现

oracle 中使用示例代码:

SELECT T.ID FROM bas_basic_tree T CONNECT BY PRIOR T.ID = T.PID START WITH T.ID = #{id}

mysql 中使用示例代码:

SELECT ID FROM bas_basic_tree T, (SELECT @DATAS := getChildId_bas_basic_tree (#{id})) x WHERE find_in_set (ID, @DATAS)

mysql 方法的实现:

-- 在navcat中的查询下执行以下命令 drop function if exists getChildId_bas_basic_tree; DELIMITER // create function getChildId_bas_basic_tree(rootId varchar(20)) returns varchar (1000) BEGIN DECLARE pTemp VARCHAR(1000); DECLARE cTemp VARCHAR(1000); -- 节点ID(临时变量) SET pTemp = '$'; SET cTemp =cast(rootId as CHAR); -- 把rootId强制转换为字符。 WHILE cTemp is not null DO SET pTemp = concat(pTemp,',',cTemp); -- 把所有节点连接成字符串。 SELECT group_concat(id) INTO cTemp FROM bas_basic_tree WHERE FIND_IN_SET(pid,cTemp)>0; END WHILE; RETURN pTemp; END // DELIMITER ;

2.多个子递归查询的实现

oracle 中使用示例代码:

SELECT T.ID FROM bas_basic_tree T CONNECT BY PRIOR T.ID = T.PID START WITH T.ID in( #{ids} ) -- 其中ids比如是 ('1', '2') 这种

mysql 中使用示例代码:

SELECT * FROM bas_basic_tree T , (select @DATAK := ( SELECT -- 使用该方法把所有的ID用逗号分割连接成一个字符串 group_concat(T.ID) FROM bas_basic_tree T WHERE NAME LIKE #{orgname} -- 括号里面查询出来的结果类似与 '1,2' 这种 ) ) z, (SELECT @DATAS := getParentId_bas_basic_tree_more (@DATAK) ) x WHERE find_in_set (T.ID, @DATAS) -- 注意这里select @DATAK 与 SELECT @DATAS 顺序不能乱,否则会出现数据错误

mysql 方法的实现:

drop function if exists getChildId_bas_basic_tree_more; DELIMITER // create function getChildId_bas_basic_tree_more(nodes varchar(1000)) returns varchar (5000) BEGIN DECLARE pTemp VARCHAR(1000); DECLARE cTemp VARCHAR(5000); SET @array_content= nodes; SET @i=1; SET @count=CHAR_LENGTH(@array_content) -CHAR_LENGTH(REPLACE(@array_content,',','')) + 1; SET pTemp = '$'; WHILE @i <= @count DO SET cTemp = SUBSTRING_INDEX(SUBSTRING_INDEX(@array_content,',',@i),',',-1); WHILE cTemp is not null DO SET pTemp = concat(pTemp,',',cTemp); SELECT group_concat(id) INTO cTemp FROM bas_basic_tree WHERE FIND_IN_SET(pid,cTemp) > 0; END WHILE; SET @i = @i + 1; END WHILE; RETURN pTemp; END // DELIMITER ;

实现父递归查询

1.单个父递归查询的实现

oracle 中使用示例代码:

SELECT T.ID FROM bas_basic_tree T CONNECT BY PRIOR T.PID = T.ID START WITH T.ID = #{id}

mysql 中使用示例代码:

SELECT ID FROM bas_basic_tree T, (SELECT @LIST := getParentId_bas_basic_tree (#{id})) x WHERE find_in_set (ID, @LIST)

mysql 方法的实现:

-- 在navcat中的查询下执行以下命令 drop function if exists getParentId_bas_basic_tree; DELIMITER // create function getParentId_bas_basic_tree(rootId varchar(20)) returns varchar (1000) BEGIN DECLARE fid varchar(100) default ''; DECLARE str varchar(1000) default rootId; -- 节点ID(临时变量) WHILE rootId is not null do SET fid =(SELECT pid FROM bas_basic_tree WHERE id = rootId); IF fid is not null THEN SET str = concat(str, ',', fid); SET rootId = fid; ELSE SET rootId = fid; END IF; END WHILE; return str; END // DELIMITER ;

2.多个父递归查询的实现

oracle 中使用示例代码:

SELECT T.ID FROM bas_basic_tree T CONNECT BY PRIOR T.PID = T.ID START WITH T.ID in( #{ids} ) -- 其中ids比如是 ('1', '2') 这种

mysql 中使用示例代码:

SELECT T.* FROM bas_basic_tree T , (select @DATAK := ( SELECT -- 使用该方法把所有的ID用逗号分割连接成一个字符串 group_concat(T.ID) FROM bas_basic_tree T WHERE NAME LIKE #{orgname} -- 括号里面查询出来的结果类似与 '1,2' 这种 ) ) zz, (SELECT @DATAS := getParentId_bas_basic_tree_more (@DATAK) ) x WHERE find_in_set (T.ID, @DATAS)

mysql 方法的实现:

-- 在navcat中的查询下执行以下命令 drop function if exists getParentId_bas_basic_tree_more; DELIMITER // create function getParentId_bas_basic_tree_more(nodes varchar(1000)) returns varchar (5000) BEGIN DECLARE pTemp VARCHAR(1000); DECLARE cTemp VARCHAR(5000); DECLARE xTemp varchar(100); SET @array_content= nodes; SET @i=1; SET @count=CHAR_LENGTH(@array_content) -CHAR_LENGTH(REPLACE(@array_content,',','')) + 1; SET pTemp = nodes; WHILE @i <= @count DO SET cTemp=SUBSTRING_INDEX(SUBSTRING_INDEX(@array_content,',',@i),',',-1); WHILE cTemp is not null DO SET xTemp = (SELECT pid FROM bas_basic_tree WHERE id = cTemp); IF xTemp is not null THEN SET pTemp = concat(pTemp, ',', xTemp); set cTemp = xTemp; ELSE set cTemp = xTemp; END IF; END WHILE; SET @i = @i + 1; END WHILE; RETURN pTemp; END // DELIMITER ;
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    694 引用 • 537 回帖
  • SQL
    129 引用 • 396 回帖 • 3 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 369 关注
  • QQ

    1999 年 2 月腾讯正式推出“腾讯 QQ”,在线用户由 1999 年的 2 人(马化腾和张志东)到现在已经发展到上亿用户了,在线人数超过一亿,是目前使用最广泛的聊天软件之一。

    45 引用 • 557 回帖
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 3 关注
  • OneDrive
    2 引用 • 1 关注
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    554 引用 • 675 回帖
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 562 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    135 引用 • 798 回帖
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    167 引用 • 408 回帖 • 483 关注
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    76 引用 • 1742 回帖
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    8 引用 • 26 回帖
  • FreeMarker

    FreeMarker 是一款好用且功能强大的 Java 模版引擎。

    23 引用 • 20 回帖 • 473 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    54 引用 • 37 回帖
  • 开源中国

    开源中国是目前中国最大的开源技术社区。传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。

    7 引用 • 86 回帖 • 1 关注
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    43 引用 • 44 回帖
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    326 引用 • 1395 回帖
  • 招聘

    哪里都缺人,哪里都不缺人。

    188 引用 • 1057 回帖 • 2 关注
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 66 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖
  • 学习

    “梦想从学习开始,事业从实践起步” —— 习近平

    172 引用 • 541 回帖
  • VirtualBox

    VirtualBox 是一款开源虚拟机软件,最早由德国 Innotek 公司开发,由 Sun Microsystems 公司出品的软件,使用 Qt 编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。

    10 引用 • 2 回帖 • 16 关注
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    42 引用 • 130 回帖 • 252 关注
  • Rust

    Rust 是一门赋予每个人构建可靠且高效软件能力的语言。Rust 由 Mozilla 开发,最早发布于 2014 年 9 月。

    59 引用 • 22 回帖 • 2 关注
  • 阿里云

    阿里云是阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供云服务器、云数据库、云安全等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。

    85 引用 • 324 回帖 • 1 关注
  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    337 引用 • 324 回帖
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖
  • Sillot

    Insights(注意当前设置 master 为默认分支)

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。

    主仓库地址:Hi-Windom/Sillot

    文档地址:sillot.db.sc.cn

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    3. ⚠️ 汐洛绞架基于思源笔记,开发者尽最大努力与思源笔记保持兼容,但无法实现 100% 兼容
    29 引用 • 25 回帖 • 142 关注
  • 笔记

    好记性不如烂笔头。

    312 引用 • 794 回帖