手机
当前位置:查字典教程网 >编程开发 >Oracle教程 >oracle 树查询 语句
oracle 树查询 语句
摘要:格式:SELECTcolumnFROMtable_nameSTARTWITHcolumn=valueCONNECTBYPRIOR父主键=子外...

格式:

SELECT column

FROM table_name

START WITH column=value

CONNECT BY PRIOR 父主键=子外键

select lpad(' ',4*(level-1))||name name,job,id,super from emp

start with super is null

connect by prior id=super

例子:

原始数据:select no,q from a_example2

NO NAME

---------- ------------------------------

001 a01

001 a02

001 a03

001 a04

001 a05

002 b01

003 c01

003 c02

004 d01

005 e01

005 e02

005 e03

005 e04

005 e05

需要实现得到结果是:

001 a01;a02;a03

002 b01

003 c01;c02

004 d01

005 e01;e02;e03;e04;e05

思路:

1、ORACLE8.1之后有个connect by 子句,取出整棵树数据。

create table a_example1

(

no char(3) not null,

name varchar2(10) not null,

parent char(3)

)

insert into a_example1

values('001','老王',null)

insert into a_example1

values('101','老李',null)

insert into a_example1

values('002','大王1','001')

insert into a_example1

values('102','大李1','101')

insert into a_example1

values('003','大王2','001')

insert into a_example1

values('103','大李2','101')

insert into a_example1

values('003','小王1','002')

insert into a_example1

values('103','小李1','102')

NONAMEPARENT

001 老王

101 老李

002 大王1 001

102 大李1 101

003 大王2 001

103 大李2 101

003 小王1 002

103 小李1 102

//按照家族树取数据

select *from a_example1

select level,sys_connect_by_path(name,'/') path

from a_example1

start with /*name = '老王' and*/ parent is null

connect by parent = prior no

结果:

1 /老王

2 /老王/大王1

3 /老王/大王1/小王1

2 /老王/大王2

1 /老李

2 /老李/大李1

3 /老李/大李1/小李1

2 /老李/大李2

按照上面思路,我们只要将原始数据做成如下结构:

NO NAME

001 a01

001 a01/a02

001 a01/a02/a03

001 a01/a02/a03/a04

001 a01/a02/a03/a04/a05

002 b01

003 c01

003 c01/c02

004 d01

005 e01

005 e01/e02

005 e01/e02/e03

005 e01/e02/e03/e04

005 e01/e02/e03/e04/e05

最后按NO分组,取最大的一个值即为所需的结果。

NO NAME

001 a01/a02/a03/a04/a05

002 b01

003 c01/c02

004 d01

005 e01/e02/e03/e04/e05

SQL语句:

select no,max(sys_connect_by_path(name,';')) result from

(select no,name,rn,lead(rn) over(partition by no order by rn) rn1

from (select no,name,row_number() over(order by no,name desc) rn from a_example2)

)

start with rn1 is null connect by rn1 = prior rn

group by no

语句分析:

1、 select no,name,row_number() over(order by no,name desc) rn from a_example2

按照NO升序排序,同时按照NAME降序排序,产生伪列,目的是要形成树结构

NONAMERN

001 a03 1

001 a02 2

001 a01 3

002 b01 4

003 c02 5

003 c01 6

004 d01 7

005 e05 8

005 e04 9

005 e03 10

005 e02 11

005 e01 12

2、select no,name,rn,lead(rn) over(partition by no order by rn) rn1

from ( select no,name,row_number() over(order by no,name desc) rn from a_example2)

生成家族谱,即子节点与父节点有对应关系,对应关系通过rn和 rn1。其中lead为上一条记录的RN值

NONAMERNRN1 001 a03 1 2 --

说明:针对NO=001来说,其下一条记录的RN=2 001 a02 2 3--说明:针对NO=001来说,其下一条记录的RN=3 001 a01 3 --说明:针对NO=001来说,其下一条记录的RN IS NULL

002 b01 4 003 c02 5 6 003 c01 6 004 d01 7 005 e05 8 9 005 e04 9 10 005 e03 10 11 005 e02 11 12 005 e01 12

3、select no,sys_connect_by_path(name,';') result from

(select no,name,rn,lead(rn) over(partition by no order by rn) rn1

from ( select no,name,row_number() over(order by no,name desc) rn from a_example2))

start with rn1 is null connect by rn1 = prior rn

正式生成树

NORESULT

001 ;a01

001 ;a01;a02

001 ;a01;a02;a03

002 ;b01

005 ;e01

005 ;e01;e02

005 ;e01;e02;e03

005 ;e01;e02;e03;e04

005 ;e01;e02;e03;e04;e05

003 ;c01

003 ;c01;c02

004 ;d01

将上面结果按照NO分组,取result最大值即可,所以将上述语句改为

select no,max(sys_connect_by_path(name,';')) result from

(select no,name,rn,lead(rn) over(partition by no order by rn) rn1

from (select no,name,row_number() over(order by no,name desc) rn from a_example2)

)

start with rn1 is null connect by rn1 = prior rn

group by no

得到所需结果。

【oracle 树查询 语句】相关文章:

Oracle常见错误诊断

Oracle轻松取得建表和索引的DDL语句

新Orcas语言特性-查询句法

Oracle PL/SQL语言入门基础

oracle表压缩技术

Oracle xml 转换

oracle数据库补丁列表查询

oracle常用sql语句

oracle替代变量

oracle导入导出

精品推荐
分类导航