Level是层次查询的一个伪列,如果有level,必须有connect by,start with可以没有。Lpad是在一个string的左边添加一定长度的字符,并且满足中间的参数长度要求,不满足自动添加。例如现在的需求是,输出s_emp等级报表,root 节点的last_name 不变,比如第2 等级,也就是level=2的前面加两个_符号,level=3的前面加4个。这样我们可以得到一个公式就是:
无限层次树形笔记本Lpad(last_name,length(last_name)+(level*2)-2,_)
可以得出下面的语句:
select level,id,manager_id,lpad(last_name,length(last_name)+(level*2)-2,_),title,prior
last_name from s_emp
start with manager_id is null
connect by prior id=manager_id;
select 中的prior last_name是输出其父亲的last_name.这个语句执行的结果如下:
2.4 修剪branches
上面已经提到,where子句会将节点删除,但是其后代不会受到影响,connect by 中加上条件会将满足条件的整个树枝包括后代都删除。要注意,如果是connect by 之后加条件正好条件选到根,那么结果和没有加一样,如图所示:
2.5 层次查询限制
1.层次查询from 之后如果是table,只能是一个table无限层次树形笔记本 ,不能有join无限层次树形笔记本。
2.from之后如果是view,则view不能是带join的。
3.使用order by子句,order 子句是在等级层次做完之后开始的,所以对于层次查询来说没有什么意义,除非特别关注level,获得某行在层次中的深度,但是这两种都会破坏层次。见3 增强特性中的使用siblings排序。
4.在start with中表达式可以有子查询,但是connect by中不能有子查询。
以上是10g之前的限制,10g之后可以使用带join的表和视图,connect by中可以使用子查询。
2.6 应用
1)查询每个等级上节点的数目
先查看总共有几个等级:
select count(distinct level)
from s_emp
start with manager_id is null
connect by prior id=manager_id;
要查看每个等级上有多少个节点,只要按等级分组,并统计节点的数目即可,可以这样写:
select level,count(last_name)
from s_emp
start with manager_id is null
connect by prior id=manager_id
group by level;
2)格式化报表
见2.3.
3)查看等级关系
有一个常见的需求,比如给定一个具体的emp 看是否对某个emp 有管理权,也就是从给定的节点寻找,看其子树节点中能否找到这个节点。如果找到,返回,找不到,no rows returned.
比如对于s_emp表,从根节点,也就是manager_id is null的开始找,看first_name= Elena是否被它管理,语句如下:
select level,a.* from
s_emp a
where first_name=Elena –被管理的节点
start with manager_id is null –开始节点
connect by prior id=manager_id;
下一篇:树形结构的父子关系,你可以控制
文章地址:https://www.tianxianmao.com/article/other/sylevelhlpadgshbb.html