点击上方 IT牧场 ,选择 置顶或者星标
技术干货每日送达!
前言
最近在做的业务场景涉及到了数据库的递归查询。我们公司用的 Oracle ,众所周知,Oracle 自带有递归查询的功能,所以实现起来特别简单。
但是,我记得 MySQL 是没有递归查询功能的,那 MySQL 中应该怎么实现呢?
于是,就有了这篇文章。
文章主要知识点:
- Oracle 递归查询, start with connect by prior 用法
- find_in_set 函数
- concat,concat_ws,group_concat 函数
- MySQL 自定义函数
- 手动实现 MySQL 递归查询
Oracle 递归查询
在 Oracle 中是通过 start with connect by prior 语法来实现递归查询的。
按照 prior 关键字在子节点端还是父节点端,以及是否包含当前查询的节点,共分为四种情况。
prior 在子节点端(向下递归)
第一种情况:start with 子节点id = ' 查询节点 ' connect by prior 子节点id = 父节点id
select * from dept start with id='1001' connet by prior id=pid;
这里,按照条件 id='1001' 对当前节点以及它的子节点递归查询。查询结果包含自己及所有子节点。
第二种情况:start with 父节点id= ' 查询节点 ' connect by prior 子节点id = 父节点 id
select * from dept start with pid='1001' connect by prior id=pid;
这里,按照条件 pid='1001' 对当前节点的所有子节点递归查询。查询结果只包含它的所有子节点,不包含自己。
其实想一想也对,因为开始条件是以父节点为根节点,且向下递归,自然不包含当前节点。
prior 在父节点端(向上递归)
第三种情况:start with 子节点id= ' 查询节点 ' connect by prior 父节点id = 子节点id
select * from dept start with id='1001' connect by prior pid=id;
这里按照条件 id='1001' ,对当前节点及其父节点递归查询。查询结果包括自己及其所有父节点。
第四种情况:start with 父节点id= ' 查询节点 ' connect by prior 父节点id = 子节点id
select * from dept start with pid='1001' connect by prior pid=id;
这里按照条件 pid='1001',对当前节点的第一代子节点以及它的父节点递归查询。查询结果包括自己的第一代子节点以及所有父节点。(包括自己)