天天看點

自我總結-oracle遞歸查詢-一種查詢結果的三種查詢方式

去年八月,項目中需要查詢出分類樹的層級結構,根節點和各個葉子節點都存儲在同一表中,通過某個id進行關聯;

當時由于是初出茅廬,剛入職場,加上項目納期比較趕,隻求結果不問過程,便粗略了解了該表及關聯屬性表的結構,寫了這樣的查詢語句:

select temp.name,t1.value as classname from (select t.name,t.ida2a2
 from LWCSTRUCTENUMATTTEMPLATE t start with t.ida2a2=468955 
 connect by prior t.ida3a4=t.ida2a2) temp,LWCLocalizablePropertyValue t1
 ,LWCPROPERTYDEFINITION t2 where t1.ida3b4=temp.ida2a2 and 
 t1.ida3a4=t2.ida2a2 and t2.name='displayName'
           

其主要是通過oracle的start with ...connect by prior 函數來查詢出分類樹的各個節點,再對查詢結果通過    String.insert(0, rs.getString("classname") + "/")拼接得到;

後來項目需求增加,要通過葉子節點導入相關屬性資料,需要擷取到節點全路徑與待導入路徑比對,仔細研究後發現節點表的關聯關系與最開始了解的有所誤差,于是便有了如下查詢語句:

select t.Ida2a2,RPAD(' ',(LEVEL-1)*4)||t.NAME as name,
t.ida3a4,t2.value,LEVEL From LWCStructEnumAttTemplate t,LWCLocalizablePropertyValue t2 where
 t2.ida3b4=t.ida2a2 start with t.ida2a2=468955 connect by PRIOR t.ida3a4= t.ida2a2 order by Level desc;
           

仍是通過start with ...connect by prior 函數來擷取節點的層級結構,通過level僞列來實作分層查詢和排序,再從LWCLocalizablePropertyValue表中擷取到相應的顯示名稱,仍舊是通過對查詢結果進行字元串拼接得到分類全路徑;

再後來細想,為什麼非要再查詢後再對查詢結果進行字元串拼接呢?oracle是否有提供相關函數可以幫助實作呢?

經過查詢資料後,得到如下查詢語句:

select listagg(t2.value, '/')within group(order by Level desc) as classname
 from LWCSTRUCTENUMATTTEMPLATE t ,LWCLocalizablePropertyValue t2 where
 t2.ida3b4=t.ida2a2 start with t.ida2a2=468955 
 connect by prior t.ida3a4=t.ida2a2  ;
           

大體的查詢思路還是遞歸查詢那一套,隻不過通過listagg()within group()函數來對查詢結果進行拼接,即查詢後一步到位,不需要再對查詢結果周遊拼接了。