Oracle为数据处理人员提供了强大的处理性能的同时,也提功了很多成熟的特殊需求解决方案,start with是Oracle提供的层级数据求解关系,下面将用一个案例介绍其用法

当前拥有数据表te(组织机构表),表内存在zzbm(组织编码)、sjzzbm(上级组织编码)字段,数据中存在部门级组织机构、单位级组织结构两种数据,并提供zzlx(组织类型)这一字段区分数据所属种类,该字段值1标识单位,2标识部门

如上条件下,现有一需求为:求出该表中所有部门数据所属的末级单位的组织编码,数据样例如下
在这里插入图片描述
该需求正确结果如下—mjdw(末级单位)
在这里插入图片描述
从结果中,可以分析得到一下几点
1、单位级数据无需求该字段值
2、单位之间也存在层级关系
3、末级单位不能受单位之间层级关系的影响


知道需求之后我们来了解一下Oracle的start with算法,内部核心是什么,见下图
在这里插入图片描述
start with算法内部的核心是树,或者叫森林算法更贴切一点,它以树顶点与叶子节点的方式求出层级关系

如图中圆代表单位数据,三角代表部门数据,算法的使用就是一个选定谁为顶点,以及其他树叶子节点以什么条件关联顶点的过程


但是该算法有两个需要着重注意的特点:

1、如果顶点不唯一,且顶点之间也满足树于叶子的条件,就是说一个树顶点本身又是其他顶点的子节点,那么就会影响下面所有子节点的层级数据,最终会存在如下的多条数据
在这里插入图片描述
因此我们在使用的时候要注意这一情况,避免对结果产生影响

2、在数算法计算的过程中,如果数据发生了断路,既中有有部分节点不存在,此时树计算不会被彻底打断,断点后的树关系任然会计算,只是树的附属属性,比如通过方法获取到的顶点等等这些会发生异常,就需要实际情况而定了


言归正传,我们开始解决需求,解决思路如下

1、先确定出所有的树,同时计算树中各个子节点到顶点的层级
2、筛选出所有部门级别的层级数据
3、使用排序开窗函数,区分同一子节点与不同顶点的层级次序
4、对第三步结果中的层次次序取最小层级数据,既是需要的末级单位

整体sql如下,start with用来确定顶点范围,connect by用来指定从顶点开始与子节点之间的关系,PRIOR关键字用来在关系中确定关系中的父节点PRIOR 上游数据的字段=当前数据的字段,LEVEL关键字获取当前数据层级,CONNECT_BY_ROOT用来查询当前节点所属顶点的某个数据,通常会被用来查询当前节点的顶点是谁,Oracle也提供了其他配合使用的内建函数,常用的还有SYS.CONNECT_BY_PATH(字段名,分隔符)函数,可求出自顶点到该子节点之间的所有节点某列值的聚合结果并用指定的符号分割

with te1 as (
    --第一层,先确定出所有的树,同时计算树中各个子节点到顶点的层级
    SELECT
        zzbm,
        sjzzbm,
        zzlx,
        CONNECT_BY_ROOT(zzbm) rt,
        LEVEL lv  
    FROM te 
    start with te.zzbm in (select zzbm from te where te.zzlx='1')
    connect by PRIOR zzbm=sjzzbm
), te2 as (
    --第二层,筛选出所有部门级别的层级数据
    select 
    	te1.zzbm,
    	te1.sjzzbm,
    	te1.rt,
    	te1.zzlx,
    	te1.lv
    from te1 where te1.zzlx='2'
), te3 as (
    --第三层,使用排序开窗函数,区分同一子节点与不同顶点的层级次序
    select 
    	te2.zzbm,
    	te2.sjzzbm,
    	te2.zzlx,
    	te2.rt,
    	te2.lv,
    	row_number() over(partition by te2.zzbm order by te2.lv) ord
    from te2
)
--第四层,对层次次序取最小层级数据,既是需要的最后一级单位
select 
    te3.zzbm,
    te3.sjzzbm,
    te3.zzlx,
    te3.rt,
    te3.lv,
	te3.ord
from  te3 where te3.ord=1;

最后在提醒读者一句,Oracle中的数据通常较多,推荐你在使用start with时在子节点,也就是案例中的sjzzbm列添加索引,因为在计算时,Oracle需要不断的递归查询该列数据,如果数据量大又无索引,那么效率会相当感人

Logo

电影级数字人,免显卡端渲染SDK,十行代码即可调用,工业级demo免费开源下载!

更多推荐