首页 > 数据库 >Oracle 递归遍历

Oracle 递归遍历

时间:2024-04-08 14:59:04浏览次数:19  
标签:ename 遍历 递归 prior empno mgr connect Oracle 节点

1、场景递归到第几层,例如递归到第2层      

select level, --层级
wdj.*
from wip_discrete_jobs_v wdj
where 1 = 1
start with wdj.wip_entity_name = '08363790' --递归开始
connect by wdj.attribute3 = prior wdj.wip_entity_name
and level < 3;

 

2、一行数据出现两行 效果图: select level rn from dual connect by level < 2 ;

 

 

3、利用递归快速构造大量测试数据
create table TB_TEST2 (
c_id varchar2(1000),
c_date date,
c_string varchar2(1000),
c_amount number,
c_guid varchar2(1000),
c_type varchar2(1000)
);

 

批量插入数据:
insert into TB_TEST2
select to_char(rownum) c_id,
sysdate + rownum / 24 / 3600 c_date,
dbms_random.string('x', 20) c_string,
trunc(dbms_random.value(0, 10000000)) c_amount,
sys_guid() c_gruid,
to_char(trunc(dbms_random.value(0, 2))) c_type
from dual
connect by level <= 1000

 

额外话题字符串排序
select to_number(x.c_id) num_asc,
x.c_date,
x.c_string,
x.c_amount,
x.c_guid,
x.c_type
from tb_test2 x
order by to_number(x.c_id) asc

 

  简单树查找 案例: 查找上下级关系
  • oracle树查询需要使用到start with ... connect by prior...子句
--采用oracle树查询实现
select empno, ename, mgr, (prior ename) as mgrname --上级名称
from scott.emp
start with empno = 7566 --以7566为起点向下递归查找
connect by (prior empno) = mgr --上一级的员工编码等于本级的上级领导编码

 

  根节点、叶子节点、分支节点 案例:判别是否为根节点、叶子节点、分支节点 根节点:整个树的最上层(即level = 1) 叶子节点:在树中没有子级(即connect_by_isleaf = 1) 分支节点:排除根节点以及不是叶子节点的都是分支节点(即connect_by_isleaf = 0 and level > 1)
select e.empno,
e.ename,
e.mgr,
(prior ename) as mgrname,
level as 层级,
case
when level = 1 then
'根节点'
else
null
end as 是否根节点,
case
when connect_by_isleaf = 1 then
'叶子节点(该员工不属于其他员工的上级)'
else
null
end as 是否叶子节点,
case
when connect_by_isleaf = 0 and level > 1 then --需要排除根节点(level = 1)
'分支节点'
else
null
end as 是否分支节点
from scott.emp e
start with e.empno = 7566
connect by (prior empno) = e.mgr

 

  查看根节点到当前节点的路径
select t.empno, t.ename, t.mgr, t.mgrname, substr(t.enames, 2) as enames
from (select e.empno,
e.ename,
e.mgr,
(prior ename) as mgrname,
sys_connect_by_path(e.ename, ',') as enames
from scott.emp e
start with e.empno = 7566
connect by (prior empno) = e.mgr) t

 

  树查询中的排序不能直接使用order by,而应该使用order siblings by, 对于树形数据,我们只需要针对同一条路径下的分支进行排序,这样就不会影响到整棵树的数据 --直接加order by
select lpad('-', (level - 1) * 2, '-') || e.empno as empno,
e.empno,
e.ename,
e.mgr,
(prior ename) as mgrname
from scott.emp e
start with e.empno = 7566
connect by (prior empno) = e.mgr
order by e.empno desc;

 

--使用order siblings by
select lpad('-', (level - 1) * 2, '-') || e.empno as empno,
e.empno,
e.ename,
e.mgr,
(prior ename) as mgrname
from scott.emp e
start with e.empno = 7566
connect by (prior empno) = e.mgr
order siblings by e.empno desc

 

  树查找中的where子句
  • 在树形查询中,where子句过滤的对象是树查询的结果,所以如果要先过滤再进行树查询,那么需要嵌套一个子查询
  • select e.empno, e.ename, e.mgr from scott.emp e where e.deptno = 20;
  • 如上图,20号部门没有mgr is null的数据。
  • --先查询树数据,再进行过滤
select e.empno, e.ename, e.mgr, e.deptno, (prior ename) as mgrname
from scott.emp e
where e.deptno = 20
start with e.mgr is null
connect by (prior empno) = e.mgr;

 

--等价于
select *
from (select e.empno, e.ename, e.mgr, e.deptno, (prior ename) as mgrname
from scott.emp e
start with e.mgr is null
connect by (prior empno) = e.mgr) t
where t.deptno = 20;

 

  如果使用以上sql直接加where的话,数据过滤就不正确了,下面那个sql就是等价的,它是先进行树查询,然后再过滤整个树查询结果,因为20号部门没有mgr is null的数据,而看下面的查询结果却返回了数据,所以数据查询不正确 0 正确的做法如下: --先过滤数据,再进行树查询
select e.empno, e.ename, e.mgr, e.deptno, (prior ename) as mgrname
from (select * from scott.emp where deptno = 20) e
where e.deptno = 20
start with e.mgr is null
connect by (prior empno) = e.mgr;

 

  查询树形的一个分支
  • 查询树形的分支不能使用where,只需要通过start with xx指定开始遍历的节点即可
案例:查询员工编码为7698(BLAKE)及其下属员工 --案例:查询员工编码为7698(BLAKE)及其下属员工
select e.empno,
e.ename,
e.mgr,
(prior ename) as 所属上级,
level as 层次,
decode(connect_by_isleaf, 1, '是', '否') as 是否叶子节点
from scott.emp e
start with e.empno = 7698
connect by (prior empno) = e.mgr

 

去除树形的一个分支
  • 同查询树形的分支不能使用where,如果要去除树形的一个分支, 因为树查询的过滤条件通过connect by (xx = yy)指定,所以可以直接在connect by 后面加条件过滤即可
案例:去除员工编码为7698(BLAKE)及其下属员工在树查询结果中分支
select e.empno,
e.ename,
e.mgr,
(prior ename) as 所属上级,
level as 层次,
decode(connect_by_isleaf, 1, '是', '否') as 是否叶子节点
from scott.emp e
start with e.mgr is null
connect by (prior empno) = e.mgr
and e.empno != 7698 --去除某个分支

 

标签:ename,遍历,递归,prior,empno,mgr,connect,Oracle,节点
From: https://www.cnblogs.com/ivenlin/p/18121125

相关文章

  • 递归寻找节点
    publicclassFileNode:PropertyChangedBase{publicFileNode(){this.Files=newObservableCollection<FileNode>();this.IsFile=false;}privatestring_name=string.Empty;......
  • Elasticsearch,使用scroll实现遍历(分页)查询
    为什么要使用scroll查询在使用es中,当某个index存贮的数据超过10000时,只能查询到10000的数据。因为index.max_result_window默认值是10000。并且使用游标查询可以在一次查询中获取大量文档,并且保持查询快照状态,允许用户多次检索数据而不影响其他并发请求。scroll查......
  • 不同于Oracle:SEQUENCE的区别
    不同于Oracle:SEQUENCE的区别前言在使用Oracle数据库SEQUENCE功能时,发现Oracle对边界处理比较奇怪。刚好GreatSQL也支持SEQUENCE,就拿来一起比较一下。先说结论:GreatSQL的使用基本和Oracle基本一致,但是对STARTWITH的边界限制有所不同。本次测试使用数据库的版本号#Oracle......
  • oracle 数据库精简模式磁盘空间回收处理
            最近遇到的项目中,需要部署几套oracle19cRAC数据库,在进行存储磁盘卷划分的时候,发现只能分配精简卷模式的磁盘,出于性能以及安全考虑,咨询存储原厂答曰该powerstore存储只支持精简磁盘卷模式。    自oracle12c开始,asm开始支持精简卷模式,asm磁盘组......
  • 基于C语言用递归思想实现斐波那契数列的函数设计
    用C语言并利用递归思想实现设计一个程序,完成斐波那契数列的函数设计,利用递归实现!/********************************************************************* filename: * author :[email protected]* date :2024/04/07* function:利用递归思想实现设计......
  • 二叉树的非递归遍历
    感谢b站up主优雅的代码:https://space.bilibili.com/95715842二叉树的非递归遍历非递归的先序遍历思想:利用栈先进后出的性质。将根节点入栈,(根节点出栈的同时先拉右子树入栈,之后拉左子树入栈;左子树出栈的同时先拉其右子树入栈);依次继续。voidpreOrder(TreeNode*root){......
  • 【SQL】Oracle的内连接、左外连接、右外连接及全外连接
    理解Oracle的各种连接方法的最有效的方法就是“躬亲”,在实践中去深刻理解内连接,左外连接,右外连接,全外连接的概念的和效果。1.创建测试表并准备测试数据sec@ora10g>createtablea(anumber(1),bnumber(1),cnumber(1));sec@ora10g>createtableb(anumber(1),dnumber(1),e......
  • Acwing2024蓝桥杯递归
    模板:欧几里得算法//若a,b互质则返回1,否则返回0intgcd(inta,intb){returnb?gcd(b,a%b):a;}题目:AcWing1360.有序分数暴力模拟法(AC):#include<iostream>#include<algorithm>#definexfirst#defineysecondusingnamespacestd;intn;typed......
  • bs4的使用 遍历文档树
     bs4的使用#遍历文档树#搜索文档树(5种过滤规则)#limit和recursive参数importrequests#pip3installbeautifulsoup4解析html和xml,修改html和xmlfrombs4importBeautifulSoup#res=requests.get('https://www.autohome.com.cn/news/1/#liststart')##withop......
  • Oracle EBS 查询用户密码
    程序包头: CREATEORREPLACEPACKAGEcux_fnd_web_secISFUNCTIONget_user_pass(p_fnd_userINVARCHAR2,p_guest_loginINVARCHAR2DEFAULT'GUEST/ORACLE')RETURNVARCHAR2;FUNCTIONget_apps_pass(p_guest_loginINV......