oracle层次查询

1 定义:

层次查询使用树的遍历,走遍含树形结构的数据集合,来获取树的层次关系报表的方法

树形结构的父子关系,你可以控制:

① 遍历树的方向,是自上而下,还是自下而上

②  确定层次的开始点(root)的位置

层次查询语句正是从这两个方面来确定的,start
with确定开始点,connect by确定遍历的方向  www.2cto.com

2 语法:

注释:

① level是伪列,表示等级


from后面只能是一个表或视图,对于from是视图的,那么这个view不能包含join


Where条件限制了查询返回的行,但是不影响层次关系,属于将节点截断,但是这个被截断的节点的下层child不受影响

④ prior是个形容词,可放在任何地方

⑤ 彻底剪枝条件应放在connect
by;单点剪掉条件应放在where子句。但是,connect by的优先级要高于where,也就是sql引擎先执行connect by

⑥ 在start with中表达式可以有子查询,但是connect
by中不能有子查询

3 遍历树:

㈠ Start with子句

Start with确定将哪行作为root,如果没有start
with,则每行都当作root,然后查找其后代,这不是一个真实的查询。Start with后面可以使用子查询或者任何合法的条件表达式

例子:

[sql]

select level,id,manager_id,last_name,title from s_emp

start with title=(select title from s_emp where
manager_id is null)

connect by prior id=manager_id;

㈡ Connect by子句

Connect
by与prior确定一个层次查询的条件和遍历的方向(prior确定)

Connect by prior
column_1=column_2;

其中prior表示前一个节点的意思,可以在connect
by等号的前后,列之前,也可以放到select中的列之前  www.2cto.com

Connect by也可以带多个条件,比如 connect by prior
id=manager_id and id>10

1. )自顶向下遍历:

先由根节点,然后遍历子节点。column_1表示父key,column_2表示子key。即这种情况下:connect by
prior 父key=子key表示自顶向下,等同于connect by 子key=prior 父key.

例子:

[sql]

select level,employee_id,manager_id,last_name,job_id from s_emp

start with manager_id=100

connect by  employee_id=prior manager_id;

2. )自底向上遍历:

先由最底层的子节点,遍历一直找到根节点。与上面的相反。Connect
by之后不能有子查询,但是可以加其他条件,比如加上and id
!=2等。这句话则会截断树枝,如果id=2的这个节点下面有很多子孙后代,则全部截断不显示。

例子:

[sql]

select level,employee_id,manager_id,last_name,job_id from s_emp

start with manager_id=100    www.2cto.com

connect by prior employee_id=manager_id and
employee_id<>120;

4 使用level和lpad格式化报表:

Level是层次查询的一个伪列,如果有level,必须有connect
by,start with可以没有

Lpad是在一个string的左边添加一定长度的字符,并且满足中间的参数长度要求,不满足自动添加

例子:

[sql]

select
level,employee_id,manager_id,lpad(last_name,length(last_name)+(level*4)-4,‘_‘),job_id
from s_emp

start with manager_id=100

connect by prior employee_id=manager_id and
employee_id<>120

5 修剪branches:

where子句会将节点删除,但是其后代不会受到影响,connect by
中加上条件会将满足条件的整个树枝包括后代都删除。要注意,如果是connect by之后加条件正好条件选到根,那么结果和没有加一样

6 实际应用

1)查询每个等级上节点的数目

[sql]

先查看总共有几个等级:

select count(distinct level)

from s_emp

start with manager_id is null

connect by prior employee_id=manager_id

要查看每个等级上有多少个节点,只要按等级分组,并统计节点的数目即可,可以这样写:

select level,count(last_name)

from s_emp

start with manager_id is null

connect by prior employee_id=manager_id

group by level    www.2cto.com

2)查看等级关系

比如给定一个具体的员工看是否对某个员工有管理权

[sql]

select level,a.* from

s_emp a

where first_name=‘Douglas‘ --被管理的节点

start with manager_id is null --开始节点,即:根节点

connect by prior employee_id=manager_id

3)删除子树

比如有这样的需求,现在要裁员,将某个部门的员工包括经理全部裁掉

将id为2的员工管理的所有员工包括自己删除

[sql]

delete from s_emp where employee_id in(

elect employee_id from

s_emp a

start with employee_id=2 --从id=2的员工开始查找其子节点,把整棵树删除

connect by prior employee_id=manager_id)

4)找出每个部门的经理

[sql]

select level,a.* from

s_emp a    www.2cto.com

start with manager_id is null

connect by prior employee_id=manager_id and department_id !=prior
department_id;--当前行的dept_id不等于前一行的dept_id,即每个子树中选最高等级节点

5)查询一个组织中最高的几个等级

[sql]

select level,a.* from

s_emp a

where level <=2 –查找前两个等级

start with manager_id is null

connect by prior employee_id=manager_id and department_id !=prior
department_id;

6)合计层次

有两个需求,一是对一个指定的子树subtree做累加计算salary,一是将每行都作为root节点,然后对属于这个节点的所有子节点累加计算salary。

[sql]

第一种很简单,求下sum就可以了,语句:

select sum(salary) from

s_emp a

start with id=2—比如从id=2开始

connect by prior id=manager_id;

第2个需求,需要用到第1个,对每个root节点求这个树的累加值,然后内部层次查询的开始节点从外层查询获得。

select last_name,salary,(

select sum(salary) from

s_emp    www.2cto.com

start with id=a.id –让每个节点都成为root

connect by prior id=manager_id) sumsalary

from s_emp a;

7)找出指定层次中的叶子节点

Leaf(叶子)就是没有子孙的孤立节点。Oracle
10g提供了一个简单的connect_by_isleaf=1,0表示非叶子节点

[sql]

select level,id,manager_id,last_name, title from s_emp

where connect_by_isleaf=1 –表示查询叶子节点

start with  manager_id=2

connect by prior id=manager_id;

7 10g新特性:

① 使用SIBLINGS关键字排序

如果使用order
by排序会破坏层次,在oracle10g中,增加了siblings关键字的排序

语法:order  siblings
 by <expre>

它会保护层次,并且在每个等级中按expre排序

例子:

[sql]

select level,    www.2cto.com

employee_id,last_name,manager_id

from s_emp

start with manager_id is null

connect by prior employee_id=manager_id

order siblings by last_name;

② CONNECT_BY_ROOT

Oracle10g新增connect_by_root,用在列名之前表示此行的根节点的相同列名的值

例子:

[sql]

select connect_by_root last_name root_last_name, connect_by_root
employee_id root_id,

employee_id,last_name,manager_id

from s_emp

start with manager_id is null

connect by prior employee_id=manager_id

oracle层次查询,布布扣,bubuko.com

时间: 2024-10-11 08:48:53

oracle层次查询的相关文章

Oracle层次查询和分析函数在号段选取中的应用

转自:http://www.itpub.net/thread-719692-1-1.html 摘要一组连续的数,去掉中间一些数,如何求出剩下的数的区间(即号段)?知道号段的起止,如何求出该号段内所有的数?知道一个大的号段范围和已经取过的号段,如何求出可用的号段?利用Oracle提供的强大的查询功能以及分析函数,我们可以很轻松的解决上述问题. 关键词:号段选取.连续数.断点.层次查询.分析函数.connect by.rownum.level.lead.lag 1.        问题的提出在实际工

Oracle分区表的层次查询如何才能用到分区?

最近在调优分区表的层次查询时,发现用不到分区,做了一个实验,发现还是可以用的到的,只是写法上有些要求. drop table test; create table test ( id  number primary key, parent_id number, name varchar2(20), code varchar2(4) ) partition by list(code) ( partition p1 values('0301'), partition p2 values('0302'

oracle 层次化查询(生成菜单树等)

1.简介:Oracle层次化查询是Oracle特有的功能实现,主要用于返回一个数据集,这个数据集存在树的关系(数据集中存在一个Pid记录着当前数据集某一条记录的Id). 2.层次化查询主要包含两个子句,一个start with另一个是connect by. start with:这个子句一般用于指定层次化查询的开始节点(也就是树的最顶级节点),找到最顶级节点,然后按照一定的规则开始查找其剩余的子节点 connect by:这个子句就是上面所说的规则,用于查找剩余子节点的规则 CREATE TAB

oracle高级查询(实例基于scott用户四张表)

oracle高级查询(实例基于scott用户四张表) 分组查询 多表查询 子查询 综合实例 ======================================================================= scott用户的四张表(emp,dept,bonus,salgrade) 没有这四张表的可参考http://blog.csdn.net/love_legain/article/details/54311040进行创建 -----------------------

数据库编程3 Oracle 子查询 insert update delete 事务 回收站 字段操作 企业级项目案例

[本文谢绝转载原文来自http://990487026.blog.51cto.com] <大纲> 数据库编程3 Oracle 子查询 insert update delete 事务 回收站 字段操作 企业级项目案例 实验所用数据表 子查询,解决一步不能求解 查询工资比scott高的员工信息: 子查询知识体系搭建: 解释3,查询部门是sales的员工信息: 方法1:子查询 [方法2]:多表: 优化考虑: 解释4[select],只能放单行子查询 解释4[from] 考题:显示员工姓名,薪水 解释

【Oracle 常用查询】oracle表空间使用率统计查询

参考1 --查询表空间使用情况 SELECT Upper(F.TABLESPACE_NAME) "表空间名", D.TOT_GROOTTE_MB "表空间大小(M)", D.TOT_GROOTTE_MB - F.TOTAL_BYTES "已使用空间(M)", To_char(Round(( D.TOT_GROOTTE_MB - F.TOTAL_BYTES ) / D.TOT_GROOTTE_MB * 100, 2), '990.99') || '

Oracle 模糊查询方法

在这个信息量剧增的时代,如何帮助用户从海量数据中检索到想要的数据,模糊查询是必不可少的.那么在Oracle中模糊查询是如何实现的呢? 一.我们可以在where子句中使用like关键字来达到Oracle模糊查询的效果:在Where子句中,可以对datetime.char.varchar字段类型的列用Like关键字配合通配符来实现模糊查询,以下是可使用的通配符: (1)% :零或者多个字符,使用%有三种情况 字段 like '%关键字%'字段包含"关键字"的记录 字段 like '关键字%

Oracle分页查询语句的写法(转)

分页查询是我们在使用数据库系统时经常要使用到的,下文对Oracle数据库系统中的分页查询语句作了详细的介绍,供您参考. Oracle分页查询语句使我们最常用的语句之一,下面就为您介绍的Oracle分页查询语句的用法,如果您对此方面感兴趣的话,不妨一看. Oracle分页查询语句基本上可以按照本文给出的格式来进行套用.Oracle分分页查询格式: SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (SELECT * FROM TABLE_NAME) A WHER

ORACLE 分页查询

Oracle之分页查询 Oracle的分页查询语句基本上可以按照本文给出的格式来进行套用. 分页查询格式: SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (SELECT * FROM TABLE_NAME) A WHERE ROWNUM <= 40 ) WHERE RN >= 21 其中最内层的查询SELECT * FROM TABLE_NAME表示不进行翻页的原始查询语句.ROWNUM <= 40和RN >= 21控制分页查询的每页的范围.