Oracle 层级数据计算方式start with connect by
Oracle为数据处理人员提供了强大的处理性能的同时,也提功了很多成熟的特殊需求解决方案,start with就是Oracle提供的层级数据求解关系的解决方案,下面我将用一个实际开发案例为大家介绍其用法如当前拥有数据表te(组织机构表),表内存在zzbm(组织编码)、sjzzbm(上级组织编码)字段,数据中存在部门级组织机构、单位级组织结构两种数据,并提供zzlx(组织类型)这一字段区分数据所属种
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需要不断的递归查询该列数据,如果数据量大又无索引,那么效率会相当感人
更多推荐




所有评论(0)