sys_connect_by_path 的用法

个人觉得这个函数其实很好用,sys_connect_by_path(字段名, 2个字段之间的连接符号),注意这里的连接符号不要使用逗号,oracle会报错,如果一定要用,可以使用replace替换一下,方法如下 REPLACE(字段名,原字符,',')。
还有,这个函数使用之前必须先建立一个树,否则无用。
举个例子:
目的:将num值相等的项目写成 seq1,seq2,seq3,……的形式
(SELECT num,REPLACE(MAX(sql0), ';', ',')
                         FROM (SELECT num, sys_connect_by_path(sql1, ';') AS sql0
                              FROM (SELECT num, sql1, rn, lead(rn) over(PARTITION BY num ORDER BY rn) rn1
                                       FROM (SELECT num, sql1, row_number() over(ORDER BY num, sql1 DESC) rn FROM tlsbk))
                              START WITH num = '1' AND rn1 IS NULL
                               CONNECT BY rn1 = PRIOR rn));
结果:
num REPLACE(MAX(sql0), ';', ',')
--------------------------------------------------------
1 sql0,sql1,sql2
2 sql20,sql21,sql23,sql24,sql25
3 sql30,sql31,sql32,sql33,sql34,sql35,sql36

树结构和它的专用函数SYS_CONNECT_BY_PATH(网摘:http://blog.oracle.com.cn/html/83/t-122083.html)
简单的树型结构
关于树的普通应用
学习了下这个函数, 用ORGINDUSTRIES的表做了个测试:
正常的树型结构
select lpad(' ',6*(level-1))||industry,indlevel,indid,pindid
from ORGINDUSTRIES
start with indid=1
connect by pindid=prior indid
结果显示如下
                Indlevel   indid pindid
       服装与服饰             1          1          0
             服装             2          2             1
                   女装        3          3             2

倒型树
下面这个例子是个”倒数”—倒过来的树型结构
select lpad(' ',6*(level-1))||industry,indlevel,indid,pindid
from ORGINDUSTRIES
start with indid=20
connect by indid=prior pindid;
这是标准结果:
                            Indlevel indid pindid
二手服装                   3        20    2
   服装                    2        2        1
         服装与服饰        1        1        0
结论
无论正树还是倒树, 关键就在于connect by的条件.
正树:   必须是   ‘父’= prior ‘子’
倒树:   必须是   ‘子’= prior ‘父’

树型结构的条件过滤
采用树型结构的话, 如果我们想将树上的一个分支砍掉.   将分支后面的结构都抛弃掉, 这个可以实现麽?当然可以。 但是不是用where, where条件只能去除单一的条件。
所以, 这种树型的过滤条件就需要加在connect by上面。

测试如下:由于用真实环境比较贴近实际,所以提前用下SYS_CONNECT_BY_PATH函数来显示下环境

不加任何条件的环境:
select areaname,sys_connect_by_path(areaname,',')
from areas bb
start with areaname='中国大陆'
connect by parentareaid=prior areaid 

结果:
1        中国大陆,中国大陆
2        北京        ,中国大陆,北京
3        北京        ,中国大陆,北京,北京
4        东城区        ,中国大陆,北京,东城区
5        西城区        ,中国大陆,北京,西城区
22        广东        ,中国大陆,广东
23        广州        ,中国大陆,广东,广州
24        汕尾        ,中国大陆,广东,汕尾
25        潮阳        ,中国大陆,广东,潮阳
46        上海        ,中国大陆,上海
47        上海        ,中国大陆,上海,上海
48        黄浦区        ,中国大陆,上海,黄浦区
49        闸北区        ,中国大陆,上海,闸北区


加了where过滤条件的SQL:
select areaname,sys_connect_by_path(areaname,',')
from areas bb
where bb.areaid>861000
start with areaname='中国大陆'
connect by parentareaid=prior areaid

结果为:
2        北京        ,中国大陆,北京
3        北京        ,中国大陆,北京,北京
4        东城区        ,中国大陆,北京,东城区
5        西城区        ,中国大陆,北京,西城区
22        广东        ,中国大陆,广东
23        广州        ,中国大陆,广东,广州
24        汕尾        ,中国大陆,广东,汕尾
25        潮阳        ,中国大陆,广东,潮阳
46        上海        ,中国大陆,上海
47        上海        ,中国大陆,上海,上海
48        黄浦区        ,中国大陆,上海,黄浦区
49        闸北区        ,中国大陆,上海,闸北区

结论:去掉了“1        中国大陆,中国大陆”数据

加了connect by的过滤条件:
select areaname,sys_connect_by_path(areaname,',')
from areas bb
where bb.areaid>861000
start with areaname='中国大陆'
connect by parentareaid=prior areaid   and areaname<>'广东'

结果为:
2        北京        ,中国大陆,北京
3        北京        ,中国大陆,北京,北京
4        东城区        ,中国大陆,北京,东城区
5        西城区        ,中国大陆,北京,西城区
46        上海        ,中国大陆,上海
47        上海        ,中国大陆,上海,上海
48        黄浦区        ,中国大陆,上海,黄浦区
49        闸北区        ,中国大陆,上海,闸北区

结论:去掉了整个广东的分支,   在结果集中只有北京和上海


SYS_CONNECT_BY_PATH函数
采用SYS_CONNECT_BY_PATH函数为:

select industry,sys_connect_by_path(industry,'/')
from ORGINDUSTRIES
start with indid=3
connect by indid=prior pindid;

结果为:
女装             /女装
服装             /女装/服装
服装与服饰          /女装/服装/服装与服饰

这样的话, 就可以实现, 树结构的结果集的单行拼接:

我们只需要取最大的字段就OK了

测试如下:

select max(sys_connect_by_path(industry,'/'))
from ORGINDUSTRIES
start with indid=3
connect by indid=prior pindid;

结果为:
/女装/服装/服装与服饰


复杂的树型结构――多列变单列
树型结构也分单树和多树(我的称呼,实际上就是指单支和多支)
对于下面的这种情况, 我们必须要构造的树就属于单支树。
原始环境
环境如下:
select * from test;

结果为:
1        n1
1        n2
1        n3
1        n4
1        n5
3        t1
3        t2
3        t3
3        t4
3        t5
3        t6
2        m1

造树
脚本如下:
select no,q,
   no+row_number() over( order by no) rn,
   row_number() over(partition by no order by no) rn1
from test

结果如下:
No   Q   RN RN1
1        n1        2        1
1        n2        3        2
1        n3        4        3
1        n4        5        4
1        n5        6        5
2        m1        8        1
3        t1        10        1
3        t2        11        2
3        t3        12        3
3        t4        13        4
3        t5        14        5
3        t6        15        6

每列的目的是:
RN1列主要的目的是分组, 按照value值‘1’,我们可以start with使用它。

RN列主要用来做connect by使用。 实际上它就是我们要的树。
第一个支: 2,3,4,5,6
第二个支: 8
第三个支: 10,11,12,13,14,15

中间为什么要断掉:7,9   目的就是为了区别每个分支。 到后面看具体的SQL,就明白这里的说法了。

杀手锏
既然我们有了树, 就可以使用树型函数SYS_CONNECT_BY_PATH和connect by啦,来拼接我们所需要的多列值。

脚本如下:
select no,sys_connect_by_path(q,',')
from (
select no,q,
   no+row_number() over( order by no) rn,
   row_number() over(partition by no order by no) rn1
from test
)
start with rn1=1
connect by rn-1=prior rn

结果为:
1        ,n1
1        ,n1,n2
1        ,n1,n2,n3
1        ,n1,n2,n3,n4
1        ,n1,n2,n3,n4,n5
2        ,m1
3        ,t1
3        ,t1,t2
3        ,t1,t2,t3
3        ,t1,t2,t3,t4
3        ,t1,t2,t3,t4,t5
3        ,t1,t2,t3,t4,t5,t6

终极武器
最终我们要的值,是单列值, 其实想想, 也就是最长的一行咯。 那么就好办了。 我们直接GROUP BY ,然后取MAX值。
脚本如下:
select no,max(sys_connect_by_path(q,','))
from (
select no,q,
   no+row_number() over( order by no) rn,
   row_number() over(partition by no order by no) rn1
from test
)
start with rn1=1
connect by rn-1=prior rn
group by no

结果为:
1        ,n1,n2,n3,n4,n5
2        ,m1
3        ,t1,t2,t3,t4,t5,t6

如果觉得前面的‘,’不好看,可以使用ltrim去掉。 或者用substr也可以。
如下:
ltrim(max(sys_connect_by_path(q,',')),',')
或者
substr(max(sys_connect_by_path(q,',')),2)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: OracleSYS_CONNECT_BY_PATH是一个聚合函数,它可以返回分层查询中从根节点到当前行的路径。在使用OracleCONNECT BY子句进行分层查询时,可以使用SYS_CONNECT_BY_PATH函数来返回从根节点到当前行的路径。例如,以下查询语句将查找名为“John”的员工及其所有下属的详细信息,并返回从根节点到当前行的路径: ``` SELECT employee_name, SYS_CONNECT_BY_PATH(employee_name, '/') AS path FROM employees WHERE manager_name = 'John' CONNECT BY PRIOR employee_name = manager_name; ``` 在此查询中,SYS_CONNECT_BY_PATH(employee_name, '/')将返回从根节点到当前行的路径,以斜杠分隔符分隔。例如,如果员工名为“Bob”的员工是“John”的下属,并且它们的直接上级是“Tom”,则该查询将返回以下结果: ``` employee_name | path --------------|----------------- John | /John Samantha | /John/Samantha Bob | /John/Bob Emily | /John/Emily ``` 其中,“/John”是根节点,“/John/Samantha”是根节点到Samantha的路径,“/John/Bob”是根节点到Bob的路径,“/John/Emily”是根节点到Emily的路径。 ### 回答2: SYS_CONNECT_BY_PATHOracle中的一个函数,它用于递归查询中连接子路径的功能。 具体来说,SYS_CONNECT_BY_PATH函数可以将递归查询的结果中的每一行连接起来,形成一个路径字符串。该函数的语法为: SYS_CONNECT_BY_PATH(column, separator) 其中,column是需要连接的列名,separator是连接每个列值的分隔符。 在使用SYS_CONNECT_BY_PATH函数时,通常会搭配使用CONNECT BY语句,来进行递归查询。CONNECT BY语句用于建立递归关系,指定父子关系的条件。 在每一层递归查询中,使用SYS_CONNECT_BY_PATH函数可以将当前行的column列值与前面层次的值连接起来形成路径。这样,每一行都可以得到一个以当前行为末端的完整路径。 例如,有一个员工表格,包含员工ID、姓名和上级ID三个列。要查询出每个员工的完整路径,可以使用以下语句: SELECT emp_id, emp_name, SYS_CONNECT_BY_PATH(emp_name, '/') AS emp_path FROM employee START WITH emp_id = 1 CONNECT BY PRIOR emp_id = superior_id; 以上语句会从员工表中以ID为1的员工为起点,根据上级ID建立递归关系,并使用SYS_CONNECT_BY_PATH函数连接每个员工的姓名,形成完整的路径。 最后的结果会包含每个员工的ID、姓名以及完整的路径,路径的格式为以"/"分隔每个员工的姓名。 这就是SYS_CONNECT_BY_PATH函数在Oracle中的作用,通过连接子路径,可以更方便地处理递归查询的结果。 ### 回答3: SYS_CONNECT_BY_PATHOracle数据库中的一个内置函数,用于在使用CONNECT BY进行递归查询时,获取各级节点的路径信息。 在使用CONNECT BY进行递归查询时,可以通过使用SYS_CONNECT_BY_PATH函数,将每个节点的值与其路径连接起来,形成一个完整的路径字符串。该函数接受两个参数:要连接的值和用于分隔路径元素的分隔符。 下面是一个示例,假设有一个表employees,其中包含以下字段:emp_id、emp_name和manager_id。我们希望查询每个员工的上级经理,并将路径信息包含在结果中。 SELECT emp_name, SYS_CONNECT_BY_PATH(emp_name, '/') as path FROM employees CONNECT BY PRIOR emp_id = manager_id START WITH manager_id IS NULL; 该查询使用CONNECT BY进行递归查询,通过PRIOR关键字指定当前节点与上级节点的关联条件,START WITH关键字指定起始节点。 SYS_CONNECT_BY_PATH函数用于将emp_name值与路径分隔符'/'连接起来。例如,如果结果中的一行为"Alice", "/Bob",则表示"Alice"这个员工的上级经理为"Bob",路径为"/Bob"。 通过使用SYS_CONNECT_BY_PATH函数,我们可以方便地在递归查询的结果中获取节点的路径信息,并根据需要进行后续处理和分析。这在一些需要展示树状结构数据的场景下非常有用,例如组织架构、目录结构等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值