日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

sys_connect_by_path 用法

發(fā)布時(shí)間:2024/7/23 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sys_connect_by_path 用法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

個(gè)人覺得這個(gè)函數(shù)其實(shí)很好用,sys_connect_by_path(字段名, 2個(gè)字段之間的連接符號(hào)),注意這里的連接符號(hào)不要使用逗號(hào),oracle會(huì)報(bào)錯(cuò),如果一定要用,可以使用replace替換一下,方法如下 REPLACE(字段名,原字符,',')。
還有,這個(gè)函數(shù)使用之前必須先建立一個(gè)樹,否則無(wú)用。
舉個(gè)例子:
目的:將num值相等的項(xiàng)目寫成 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));
結(jié)果:
num REPLACE(MAX(sql0), ';', ',')
--------------------------------------------------------
1 sql0,sql1,sql2
2 sql20,sql21,sql23,sql24,sql25
3 sql30,sql31,sql32,sql33,sql34,sql35,sql36

樹結(jié)構(gòu)和它的專用函數(shù)SYS_CONNECT_BY_PATH(網(wǎng)摘:http://blog.oracle.com.cn/html/83/t-122083.html)
簡(jiǎn)單的樹型結(jié)構(gòu)
關(guān)于樹的普通應(yīng)用
學(xué)習(xí)了下這個(gè)函數(shù), 用ORGINDUSTRIES的表做了個(gè)測(cè)試:
正常的樹型結(jié)構(gòu)
select lpad(' ',6*(level-1))||industry,indlevel,indid,pindid
from ORGINDUSTRIES
start with indid=1
connect by pindid=prior indid
結(jié)果顯示如下
??????????????? Indlevel?? indid pindid
?????? 服裝與服飾???????????? 1????????? 1????????? 0
???????????? 服裝???????????? 2????????? 2???????????? 1
?????????????????? 女裝??????? 3????????? 3???????????? 2

倒型樹
下面這個(gè)例子是個(gè)”倒數(shù)”—倒過(guò)來(lái)的樹型結(jié)構(gòu)
select lpad(' ',6*(level-1))||industry,indlevel,indid,pindid
from ORGINDUSTRIES
start with indid=20
connect by indid=prior pindid;
這是標(biāo)準(zhǔn)結(jié)果:
??????????????????????????? Indlevel indid pindid
二手服裝?????????????????? 3??????? 20??? 2
?? 服裝??????????????????? 2??????? 2??????? 1
???????? 服裝與服飾??????? 1??????? 1??????? 0
結(jié)論
無(wú)論正樹還是倒樹, 關(guān)鍵就在于connect by的條件.
正樹:?? 必須是?? ‘父’= prior ‘子’
倒樹:?? 必須是?? ‘子’= prior ‘父’

樹型結(jié)構(gòu)的條件過(guò)濾
采用樹型結(jié)構(gòu)的話, 如果我們想將樹上的一個(gè)分支砍掉.?? 將分支后面的結(jié)構(gòu)都拋棄掉, 這個(gè)可以實(shí)現(xiàn)麼?當(dāng)然可以。 但是不是用where, where條件只能去除單一的條件。
所以, 這種樹型的過(guò)濾條件就需要加在connect by上面。

測(cè)試如下:由于用真實(shí)環(huán)境比較貼近實(shí)際,所以提前用下SYS_CONNECT_BY_PATH函數(shù)來(lái)顯示下環(huán)境

不加任何條件的環(huán)境:
select areaname,sys_connect_by_path(areaname,',')
from areas bb
start with areaname='中國(guó)大陸'
connect by parentareaid=prior areaid?

結(jié)果:
1??????? 中國(guó)大陸,中國(guó)大陸
2??????? 北京??????? ,中國(guó)大陸,北京
3??????? 北京??????? ,中國(guó)大陸,北京,北京
4??????? 東城區(qū)??????? ,中國(guó)大陸,北京,東城區(qū)
5??????? 西城區(qū)??????? ,中國(guó)大陸,北京,西城區(qū)
22??????? 廣東??????? ,中國(guó)大陸,廣東
23??????? 廣州??????? ,中國(guó)大陸,廣東,廣州
24??????? 汕尾??????? ,中國(guó)大陸,廣東,汕尾
25??????? 潮陽(yáng)??????? ,中國(guó)大陸,廣東,潮陽(yáng)
46??????? 上海??????? ,中國(guó)大陸,上海
47??????? 上海??????? ,中國(guó)大陸,上海,上海
48??????? 黃浦區(qū)??????? ,中國(guó)大陸,上海,黃浦區(qū)
49??????? 閘北區(qū)??????? ,中國(guó)大陸,上海,閘北區(qū)


加了where過(guò)濾條件的SQL:
select areaname,sys_connect_by_path(areaname,',')
from areas bb
where bb.areaid>861000
start with areaname='中國(guó)大陸'
connect by parentareaid=prior areaid

結(jié)果為:
2??????? 北京??????? ,中國(guó)大陸,北京
3??????? 北京??????? ,中國(guó)大陸,北京,北京
4??????? 東城區(qū)??????? ,中國(guó)大陸,北京,東城區(qū)
5??????? 西城區(qū)??????? ,中國(guó)大陸,北京,西城區(qū)
22??????? 廣東??????? ,中國(guó)大陸,廣東
23??????? 廣州??????? ,中國(guó)大陸,廣東,廣州
24??????? 汕尾??????? ,中國(guó)大陸,廣東,汕尾
25??????? 潮陽(yáng)??????? ,中國(guó)大陸,廣東,潮陽(yáng)
46??????? 上海??????? ,中國(guó)大陸,上海
47??????? 上海??????? ,中國(guó)大陸,上海,上海
48??????? 黃浦區(qū)??????? ,中國(guó)大陸,上海,黃浦區(qū)
49??????? 閘北區(qū)??????? ,中國(guó)大陸,上海,閘北區(qū)

結(jié)論:去掉了“1??????? 中國(guó)大陸,中國(guó)大陸”數(shù)據(jù)

加了connect by的過(guò)濾條件:
select areaname,sys_connect_by_path(areaname,',')
from areas bb
where bb.areaid>861000
start with areaname='中國(guó)大陸'
connect by parentareaid=prior areaid?? and areaname<>'廣東'

結(jié)果為:
2??????? 北京??????? ,中國(guó)大陸,北京
3??????? 北京??????? ,中國(guó)大陸,北京,北京
4??????? 東城區(qū)??????? ,中國(guó)大陸,北京,東城區(qū)
5??????? 西城區(qū)??????? ,中國(guó)大陸,北京,西城區(qū)
46??????? 上海??????? ,中國(guó)大陸,上海
47??????? 上海??????? ,中國(guó)大陸,上海,上海
48??????? 黃浦區(qū)??????? ,中國(guó)大陸,上海,黃浦區(qū)
49??????? 閘北區(qū)??????? ,中國(guó)大陸,上海,閘北區(qū)

結(jié)論:去掉了整個(gè)廣東的分支,?? 在結(jié)果集中只有北京和上海


SYS_CONNECT_BY_PATH函數(shù)
采用SYS_CONNECT_BY_PATH函數(shù)為:

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

結(jié)果為:
女裝???????????? /女裝
服裝???????????? /女裝/服裝
服裝與服飾????????? /女裝/服裝/服裝與服飾

這樣的話, 就可以實(shí)現(xiàn), 樹結(jié)構(gòu)的結(jié)果集的單行拼接:

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

測(cè)試如下:

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

結(jié)果為:
/女裝/服裝/服裝與服飾


復(fù)雜的樹型結(jié)構(gòu)――多列變單列
樹型結(jié)構(gòu)也分單樹和多樹(我的稱呼,實(shí)際上就是指單支和多支)
對(duì)于下面的這種情況, 我們必須要構(gòu)造的樹就屬于單支樹。
原始環(huán)境
環(huán)境如下:
select * from test;

結(jié)果為:
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

結(jié)果如下:
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列主要用來(lái)做connect by使用。 實(shí)際上它就是我們要的樹。
第一個(gè)支: 2,3,4,5,6
第二個(gè)支: 8
第三個(gè)支: 10,11,12,13,14,15

中間為什么要斷掉:7,9?? 目的就是為了區(qū)別每個(gè)分支。 到后面看具體的SQL,就明白這里的說(shuō)法了。

殺手锏
既然我們有了樹, 就可以使用樹型函數(shù)SYS_CONNECT_BY_PATH和connect by啦,來(lái)拼接我們所需要的多列值。

腳本如下:
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

結(jié)果為:
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

終極武器
最終我們要的值,是單列值, 其實(shí)想想, 也就是最長(zhǎng)的一行咯。 那么就好辦了。 我們直接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

結(jié)果為:
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)

總結(jié)

以上是生活随笔為你收集整理的sys_connect_by_path 用法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。