select SYS_CONNECT_BY_PATH(列名,'') from 表名
專注于為中小企業(yè)提供網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)服務(wù),電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)寒亭免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了上千企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴充和轉(zhuǎn)變。
start wITh 列名='0000000001'
connect by prior 列名(孩子列所有的列名)=列名(父列所有的列名)
這個查出來的樣式如下:
000000000001000000000000
不知道是不是你想要的。
可以設(shè)計成有層級的序列號,最頂級找0101就可以了
no???id_sj????id_bj??????jc
000???????????01??????????1
001??01???????0101????????2
002??0101?????010101??????3
003??010101???01010101????4
如何結(jié)構(gòu)不能變,還是如下方式,而且當前層級是幾級都不知道,就用循環(huán)吧
PS:001怎么還有上級編碼1?到底頂級在哪里?
no??id_sj?id_bj
001??1??????2
002??2??????3
003??3??????4
v_id_bj:=4;
while?v_id_sj?is?not?null?loop
select??id_sj?into?v_id_sj?from?tb?where?id_bj?=?v_id_bj;
select??id_bj?into?v_id_bj?from?tb?where?id_bj?=?v_id_sj;
end?loop;
1、創(chuàng)建測試表,create table test_connect(id number, p_id number);
2、插入測試數(shù)據(jù),
insert into test_connect values(1,1);
insert into test_connect values(2,1);
insert into test_connect values(3,2);
insert into test_connect values(4,3);
commit;
3、查詢數(shù)據(jù)表內(nèi)容,select * from?test_connect ,
4、執(zhí)行遞歸查詢語句,加入nocycle要素,不會出現(xiàn)【ORA-01436: 用戶數(shù)據(jù)中的 CONNECT BY 循環(huán)的錯誤】,執(zhí)行結(jié)果如下,
select *
from test_connect t
start with id = 4
connect by nocycle prior t.p_id = t.id
我感覺你應(yīng)該分兩步走,第一找到父節(jié)點,第二,將這些父節(jié)點加上條件。不知道你的父節(jié)點和葉子節(jié)點是怎么存儲到表中的,我舉一個父節(jié)點和葉子節(jié)點存儲在一個表中的情況給你說一下。
第一步,找到所有父節(jié)點 select 父節(jié)點 from table_A where table_A.isdetail1(意思是說,父節(jié)點不是明細項)
第二步,找到葉子節(jié)點的父節(jié)點:select 父節(jié)點 from table_A where table_A.isdetail1 and table_A.葉子節(jié)點 in(葉子節(jié)點)
第三步,再加上條件:找到葉子節(jié)點的父節(jié)點:select 父節(jié)點 from table_A where table_A.isdetail1 and table_A.葉子節(jié)點 in(葉子節(jié)點)and 父節(jié)點不符合哪些條件。
一般來說這種遞歸查詢應(yīng)該用start with connect by,不過你的表中少了一列,就是當前節(jié)點的父節(jié)點列,所以這個應(yīng)該不能用。
比如元數(shù)據(jù)為4列 其中兩列類似為
父節(jié)點編碼 當前節(jié)點編碼
010001000000 010001010000
010001010000 010001010200
那么start with connect by就可以用了,這里因為沒有這個父節(jié)點編碼的字段,所以不能用。
那么查詢就麻煩一些,我想到了一個辦法,不過是這個表結(jié)構(gòu)的特例,希望能幫到你
第一步是截取輸入的diccode的非零長度,我想到的辦法是length(trim(tailing 0 from '輸入或計算得到的diccode值'))--假設(shè)得到的是8位,假設(shè)為01000101 8位
那么所有的子節(jié)點就是 diccode like substr(diccode,1,length(trim(tailing 0 from '輸入或計算得到的diccode值')))%
意思就是 diccode like '01000101%'(這不就是所有該節(jié)點的子節(jié)點了么,包括自身)
(以上部分的寫法要斟酌一下,%是通配符,一般來說我們的寫法是like ‘a(chǎn)%’,但是單引號部分怎么寫,需不需要轉(zhuǎn)譯,反引號行不行,與%怎么連接,我沒有環(huán)境只能寫個大概意思,具體的要試驗才行。)
然后求父節(jié)點,先求上一級,diccode=(case when length(trim(tailing 0 from '輸入或計算得到的diccode值'))-20 then rpad(substr('輸入或計算得到的diccode值',1, length(trim(tailing 0 from '輸入或計算得到的diccode值'))-2),12,0) else 0 end)
意思就是:截取到01000101后,長度為8位,長度-2為6位那么就是010001,然后補足12位的0,為010001000000,也就是上一級父節(jié)點。如果輸入為010000000000,那么第一步就直接查出所有內(nèi)容了,后面這個條件用or連接,查出來的都是0,也就是diccode=0,不會干擾正常內(nèi)容的顯示。
然后繼續(xù)-2變成-4(這樣舉例就變成為010000000000),再變成-6(例子中雖然也能查出來010000000000,但是前面已經(jīng)查出,不會重復顯示的),-8(例子中等于0,那么顯示diccode=0,因為or連接所以不耽誤顯示),-10,我看了你的編碼是12位,-10應(yīng)該夠了,寫法同上,然后所有的條件用or連接,這樣不用寫過程去計算,雖然麻煩,而且速度不會太快,但是思路應(yīng)該沒錯。
其實我一直在琢磨應(yīng)該可以用start with connect by寫后面的-2到-10部分,但是如果寫成start那么這部分需要測試,我這里沒有相關(guān)的環(huán)境,所以只能是這么寫,麻煩一些。而且starwith好像沒辦法就相關(guān)子節(jié)點,所以我也不知道到底能不能用。
假設(shè)這個表名為A
select * from A START WITH id in
(select distinct id from A )
CONNECT BY PRIOR oid=id
oracle 10g之前執(zhí)行這條語句,好像oid不能為空,你可以將id為1那條數(shù)據(jù)oid欄位設(shè)置為1或者別的,反正不要是里面有的節(jié)點的id就行了