同事问我MySQL怎么递归查询,我懵逼了

一篇文章成为递归大神:MySQL递归查询(with recursive) 文章包含了MySQL with Recursive 语法的概念,结合两个常用的查询案例,分析具体使用。 其中包括 向上递归案例,向下递归案例。 最后是 注意事项 和 总结 阅读详情

此函数用于查找 str 字符串在字符串 strlist 中的位置,返回结果为 1 ~ n 。若没有找到,则返回0。

举个栗子:

select FIND_IN_SET(‘b’,‘a,b,c,d’);

结果返回 2 。因为 b 所在位置为第二个子串位置。

此外,在对表数据进行查询时,它还有一种用法,如下:

select * from dept where FIND_IN_SET(id,‘1000,1001,1002’);

结果返回所有 id 在 strlist 中的记录,即 id = ‘1000’ ,id = ‘1001’ ,id = ‘1002’ 三条记录。

看到这,对于我们要解决的递归查询,不知道你有什么启发没。

以向下递归查询所有子节点为例。我想,是不是可以找到一个包含当前节点和所有子节点的以逗号拼接的字符串 strlist,传进 find_in_set 函数。就可以查询出所有需要的递归数据了。

那么,现在问题就转化为怎样构造这样的一个字符串 strlist 。

这就需要用到以下字符串拼接函数了。

concat,concat_ws,group_concat 函数

一、字符串拼接函数中,最基本的就是 concat 了。它用于连接N个字符串,如,

select CONCAT(‘M’,‘Y’,‘S’,‘Q’,‘L’) from dual;

结果为 ‘MYSQL’ 字符串。

二、concat 是以逗号为默认的分隔符,而 concat_ws 则可以指定分隔符,第一个参数传入分隔符,如以下划线分隔。

三、group_concat 函数更强大,可以分组的同时,把字段以特定分隔符拼接成字符串。

用法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator ‘分隔符’] )

可以看到有可选参数,可以对将要拼接的字段值去重,也可以排序,指定分隔符。若没有指定,默认以逗号分隔。

对于 dept 表,我们可以把表中的所有 id 以逗号拼接。(这里没有用到 group by 分组字段,则可以认为只有一组)

MySQL 自定义函数,实现递归查询

可以发现以上已经把字符串拼接的问题也解决了。那么,问题就变成怎样构造有递归关系的字符串了。

我们可以自定义一个函数,通过传入根节点id,找到它的所有子节点。

以向下递归为例。 (讲解自定义函数写法的同时,讲解递归逻辑)

delimiter d r o p f u n c t i o n i f e x i s t s g e t c h i l d l i s t drop function if exists get_child_list dropfunctionifexistsgetc​hildl​ist
create function get_child_list(in_id varchar(10)) returns varchar(1000)
begin
declare ids varchar(1000) default ‘’;
declare tempids varchar(1000);

set tempids = in_id;
while tempids is not null do
set ids = CONCAT_WS(‘,’,ids,tempids);
select GROUP_CONCAT(id) into tempids from dept where FIND_IN_SET(pid,tempids)>0;
end while;
return ids;
end
$$
delimiter ;

(1) delimiter$$, 用于定义结束符。我们知道 MySQL 默认的结束符为分号,表明指令结束并执行。但是在函数体中,有时我们希望遇到分号不结束,因此需要暂时把结束符改为一个随意的其他值。我这里设置为 $$,意思是遇到$$ 才结束,并执行当前语句。

(2)drop function if exists get_child_list$$ 。若函数 get_child_list 已经存在了,则先删除它。注意这里需要用 当前自定义的结束符 $$ 来结束并执行语句。 因为,这里需要和下边的函数体单独区分开来。

(3)create function get_child_list 创建函数。并且参数传入一个根节点的子节点id,需要注意一定要注明参数的类型和长度,如这里是 varchar(10)。returns varchar(1000) 用来定义返回值参数类型。

(4)begin 和 end 中间包围的就是函数体。用来写具体的逻辑。

(5)declare 用来声明变量,并且可以用 default 设置默认值。

这里定义的 ids 即作为整个函数的返回值,是用来拼接成最终我们需要的以逗号分隔的递归串的。

而 tempids 是为了记录下边 while 循环中临时生成的所有子节点以逗号拼接成的字符串。

(6) set 用来给变量赋值。此处把传进来的根节点赋值给 tempids 。

(7) while do … end while; 循环语句,循环逻辑包含在内。注意,end while 末尾需要加上分号。

循环体内,先用 CONCAT_WS 函数把最终结果 ids 和 临时生成的 tempids 用逗号拼接起来。

然后以 FIND_IN_SET(pid,tempids)>0 为条件,遍历在 tempids 中的所有 pid ,寻找以此为父节点的所有子节点 id ,并且通过 GROUP_CONCAT(id) into tempids 把这些子节点 id 都用逗号拼接起来,并覆盖更新 tempids 。

等下次循环进来时,就会再次拼接 ids ,并再次查找所有子节点的所有子节点。循环往复,一层一层的向下递归遍历子节点。直到判断 tempids 为空,说明所有子节点都已经遍历完了,就结束整个循环。

这里,用 ‘1000’ 来举例,即是:(参看图1的表数据关系)

第一次循环:
tempids=1000 ids=1000 tempids=1001,1002 (1000的所有子节点)
第二次循环:
tempids=1001,1002 ids=1000,1001,1002 tempids=1003,1004,1005,1013 (1001和1002的所有子节点)
第三次循环:
tempids=1003,1004,1005,1013
ids=1000,1001,1002,1003,1004,1005,1013
tempids=1003和1004和1005及1013的所有子节点
…
最后一次循环,因找不到子节点,tempids=null,就结束循环。

(8)return ids; 用于把 ids 作为函数返回值返回。

(9)函数体结束以后,记得用结束符 $$ 来结束整个逻辑,并执行。

(10)最后别忘了,把结束符重新设置为默认的结束符分号 。

自定义函数做好之后,我们就可以用它来递归查询我们需要的数据了。如,我查询北京研发部的所有子节点。

以上是向下递归查询所有子节点的,并且包括了当前节点,也可以修改逻辑为不包含当前节点,我就不演示了。

手动实现递归查询(向上递归)

相对于向下递归来说,向上递归比较简单。

因为向下递归时,每一层递归一个父节点都对应多个子节点。

而向上递归时,每一层递归一个子节点只对应一个父节点,关系比较单一。

同样的,我们可以定义一个函数 get_parent_list 来获取根节点的所有父节点。

delimiter d r o p f u n c t i o n i f e x i s t s g e t p a r e n t l i s t drop function if exists get_parent_list dropfunctionifexistsgetp​arentl​ist
create function get_parent_list(in_id varchar(10)) returns varchar(1000)
begin
declare ids varchar(1000);
declare tempid varchar(10);

set tempid = in_id;
while tempid is not null do
set ids = CONCAT_WS(‘,’,ids,tempid);
select pid into tempid from dept where id=tempid;
end while;
return ids;
end
$$
delimiter ;

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

最后

最后,强调几点:

  • 1. 一定要谨慎对待写在简历上的东西,一定要对简历上的东西非常熟悉。因为一般情况下,面试官都是会根据你的简历来问的; 能有一个上得了台面的项目也非常重要,这很可能是面试官会大量发问的地方,所以在面试之前好好回顾一下自己所做的项目;
  • 2. 和面试官聊基础知识比如设计模式的使用、多线程的使用等等,可以结合具体的项目场景或者是自己在平时是如何使用的;
  • 3. 注意自己开源的Github项目,面试官可能会挖你的Github项目提问;

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目。

面试答案

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目。

面试答案

[外链图片转存中…(img-PyIWusWx-1710414375643)]

[外链图片转存中…(img-8pFoOXX6-1710414375643)]

[外链图片转存中…(img-7Jewdet4-1710414375643)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

两种mysql递归tree查询效率-mysql递归tree 两种mysql递归tree查询效率-mysql递归tree,提供两种递归算法 立即下载

相关推荐

MySQL通过自定义函数实现递归查询父级ID或者子级ID

主要介绍了MySQL通过自定义函数实现递归查询父级ID或者子级ID,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

MySQL5.7递归查询与CTE递归查询

MySQL 5.7递归查询,MySQL8.0的CET递归查询, This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA

llg___的博客 1万+

Abaqus 2023 保姆级安装避坑指南:从环境变量到许可证配置,一次搞定

本文提供Abaqus 2023的详细安装指南,涵盖环境变量设置、许可证配置等关键步骤,帮助用户避开常见安装陷阱。通过系统环境检查、目录结构规划、许可证服务器安装及Java环境配置等实用技巧,确保顺利完成安装并优化软件性能。

weixin_42524276的博客 426

MySQL递归函数详解:小白也能轻松上手

在MySQL中,递归函数是一种非常强大的工具,它允许我们在查询中执行递归操作,从而解决一些复杂的层级或树形结构问题。本文将详细介绍MySQL递归函数的用法,并通过实际例子帮助大家更好地理解和掌握。递归函数是一种自我调用的函数,即在函数体内部直接或间接地调用自身。在MySQL中,递归函数通常用于处理具有层级关系的数据,如组织结构、目录结构等。MySQL 8.0及更高版本支持递归查询,主要通过。用于日常数据分析补全某个时间段的日期。当然递归也可像如下用法使用,二、MySQL中的递归函数。

weixin_44228413的博客 2065

电力抄表协议DL/T645和698.45到底有啥区别?一张图帮你选对协议

本文深入对比了电力抄表协议DL/T645和DL/T698.45的技术差异,从协议架构、报文结构、功能覆盖到实施成本进行全面分析。通过实际案例和数据,揭示698.45协议在通信效率、业务扩展性和长期成本上的优势,并提供清晰的选型决策流程图,帮助工程师根据具体需求选择最适合的电力抄表协议。

weixin_38168696的博客 407

混合整数规划(MIP)在资源优化中的实战应用

本文深入探讨了混合整数规划(MIP)在资源优化中的实战应用,从菜市场采购到工厂调度,再到物流配送和钢铁厂切割问题。通过分支定界法和割平面法等技术,MIP能够有效解决包含整数和连续变量的复杂优化问题,提升企业运营效率。文章还介绍了现代求解器的优化策略和实际项目中的避坑指南,帮助读者更好地应用MIP技术。

weixin_30500105的博客 91

同事问我MySQL怎么递归查询,我懵逼了...

前言最近在做的业务场景涉及到了数据库的递归查询。我们公司用的 Oracle ,众所周知,Oracle 自带有递归查询的功能,所以实现起来特别简单。但是,我记得 MySQL 是没有递归查询功能的,那 MySQL 中应该怎么实现呢?于是,就有了这篇文章。文章主要知识点:Oracle 递归查询, start with connect by prior 用法find_in_set 函数concat,co...

十指波课堂的博客 581

k8s架构、工作流程、集群组件详解

Kubernetes(简称K8s,是因为 k 和 s 之间有八个字符)是一个开源的容器编排平台,用于管理云平台中多个主机上的容器化应用程序。它提供了一种机制,用于自动化部署、扩展和管理容器化应用程序的集群。Kubernetes的目标是让部署容器化应用程序变得简单高效。它提供了应用程序部署、规划、更新和维护的基本机制,同时具备强大的扩展性和可靠性。Kubernetes采用主从设备模型(Master-Slave架构),其中Master节点负责核心的调度、管理和运维任务,而Slave节点负责运行应用程序的容器。

qq_51545656的博客 4383

mysql中两列拼接_同事问我MySQL怎么递归查询,我懵逼了

前言最近在做的业务场景涉及到了数据库的递归查询。我们公司用的 Oracle ,众所周知,Oracle 自带有递归查询的功能,所以实现起来特别简单。但是,我记得 MySQL 是没有递归查询功能的,那 MySQL 中应该怎么实现呢?于是,就有了这篇文章。文章主要知识点:Oracle 递归查询, start with connect by prior 用法find_in_set 函数concat,con...

weixin_33819646的博客 334

深入解析SDC时钟约束:从create_clock到set_clock_groups的实战指南

本文深入解析SDC时钟约束,从create_clock到set_clock_groups的实战应用,帮助数字芯片设计工程师掌握时序约束的核心技巧。通过详细讲解时钟三要素(波形定义、不确定性和时钟关系)及实战案例,提升时钟约束的精准性和效率,避免常见设计陷阱。

weixin_29274337的博客 1080

Python 实战:爬取高德地图交通数据(路况拥堵指数分析)

高德地图是由高德软件有限公司开发的一款地图导航产品,提供详细的地图浏览、路线规划、实时路况、公共交通查询等功能。高德地图拥有庞大的用户群体和海量的交通数据,这些数据对于交通管理、城市规划、出行服务等领域具有重要的价值。通过对高德地图交通数据的分析,我们可以了解城市交通的运行状况,识别拥堵路段,预测交通流量,为交通管理部门和出行者提供决策支持。

yansideyucsdn的博客 2688

mysql查询最近一个自然周_同事问我MySQL怎么递归查询,我懵逼了

前言最近在做的业务场景涉及到了数据库的递归查询。我们公司用的 Oracle ,众所周知,Oracle 自带有递归查询的功能,所以实现起来特别简单。但是,我记得 MySQL 是没有递归查询功能的,那 MySQL 中应该怎么实现呢?于是,就有了这篇文章。文章主要知识点:Oracle 递归查询, start with connect by prior 用法find_in_set 函数concat,con...

weixin_36230515的博客 173

刷机维修进阶教程-----adb禁用错了系统app导致无法开机 如何保数据无损恢复机型

在刷机维修过程中 。我们会遇到一些由于客户使用adb指令来禁用手机app而导致手机无法开机进入系统的故障机型。通常此类问题机型有好几种解决方法。但如果客户需要保数据来恢复机型。其实操作也是很简单的.还有类似误删除应用导致不开机等等如何保数据。  通过博文了解💝💝💝    1💝💝💝----adb禁用或者删除系统app导致无法开机的几种解决方法 2💝💝💝----如何保数据来无损恢复机型 3💝💝💝----其他保数据解决系统类故障无法开机的步骤解析

小马哥的专栏 1356

mybaits 查询list第一个_同事问我MySQL怎么递归查询,我懵逼了

前言 最近在做的业务场景涉及到了数据库的递归查询。我们公司用的 Oracle ,众所周知,Oracle 自带有递归查询的功能,所以实现起来特别简单。 但是,我记得 MySQL 是没有递归查询功能的,那 MySQL 中应该怎么实现呢? 于是,就有了这篇文章。 文章主要知识点: Oracle 递归查询, start with connect by prior 用法 find_in_set 函数 co...

weixin_42467457的博客 140

OpenMVS :用 colmap制作自己的数据集 重建(用colmap计算位姿,将位姿转为MVS需要的格式)

数据集制作主要是在windows进行,比较方便。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 3326

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

concat拼接的坑 mysql_同事问我MySQL怎么递归查询,我懵逼了...

前言最近在做的业务场景涉及到了数据库的递归查询。我们公司用的 Oracle ,众所周知,Oracle 自带有递归查询的功能,所以实现起来特别简单。但是,我记得 MySQL 是没有递归查询功能的,那 MySQL 中应该怎么实现呢?于是,就有了这篇文章。文章主要知识点:Oracle 递归查询, start with connect by prior 用法find_in_set 函数concat,co...

weixin_32676101的博客 376

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

女同事问我MySQL怎么递归查询?我一顿猛虎操作,她给看懵了

前言 最近在做的业务场景涉及到了数据库的递归查询。我们公司用的 Oracle ,众所周知,Oracle 自带有递归查询的功能,所以实现起来特别简单。 但是,我记得 MySQL 是没有递归查询功能的,那 MySQL 中应该怎么实现呢? 于是,就有了这篇文章。 文章主要知识点: Oracle 递归查询, start with connect by prior 用法 find_in_set 函数 concat,concat_ws,group_concat 函数 MySQL 自定义函数 手动实现

文章中资料均可获取,有需要请添加yunduoa2019即可 143

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

使用SQL递归查询树状结构,又可以跟同事吹牛了!

在关系型数据库中,数据通常存储为二维表格(rows 和 columns)。然而,在实际业务中,很多场景下我们需要处理树状结构公司组织架构:从某个部门开始,查询其下属部门或员工。商品分类:查询某个大类下的所有子类。权限系统:根据某个角色,查询其子角色或权限继承关系。评论区:查找某个评论的所有子评论。树状数据的查询通常需要递归逻辑来处理,我看到很多人在业务代码中进行递归查询,如果数据量过大,会导致查询的次数过多,产生不必要的网络开销,而 SQL 中的递归查询。

阿杆的博客 2241

女同事问我MySQL怎么递归查询?我一顿操作猛如虎,再看她在原地杵

前言 最近在做的业务场景涉及到了数据库的递归查询。我们公司用的 Oracle ,众所周知,Oracle 自带有递归查询的功能,所以实现起来特别简单。 但是,我记得 MySQL 是没有递归查询功能的,那 MySQL 中应该怎么实现呢? 于是,就有了这篇文章。 文章主要知识点: Oracle 递归查询, start with connect by prior 用法 find_in_set 函数 concat,concat_ws,group_concat 函数 MySQL 自定义函数 手动实现

python6_quanzhan的博客 248
上一篇: 一张图搞定OAuth2,java高并发场景面试题
下一篇: 我的天!8年开发,连登陆接口都写这么烂
普通网友
博客等级 码龄5年 4697粉丝 610原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值