Oracle遞歸查詢,Oracle START WITH……CONNECT BY查詢

Oracle遞歸查詢,Oracle START WITH……CONNECT BY查詢,Oracle樹查詢sql

 

================================數據結構

©Copyright 蕃薯耀 2018年5月14日函數

https://www.cnblogs.com/fanshuyao/spa

 

說明:3d

如今表(CMM_CODE)中有一批樹結構的數據,主鍵爲CODE_ID,以字段PARENT_CODE_ID做爲父結構關聯,最頂層結構的PARENT_CODE_ID爲空,數據結構例子以下:code

Java代碼  
  1. 專業設施名稱 > 公共服務設施 > 特殊設施  

 如今要根據CODE_ID查詢出完整的樹結構名稱,經過大於號(>)拼接起來,如上面所示。blog

 

1、方法一:使用START WITH……CONNECT BY查詢,再使用SYS_CONNECT_BY_PATH拼接遞歸

Sql代碼  
  1. SELECT CC.*,SUBSTR(SYS_CONNECT_BY_PATH(CC.CODE_NAME, '>'),2) TREE_PATH   
  2. FROM CMM_CODE CC   
  3. START WITH CC.Code_Id='pn_0501004'   
  4. CONNECT BY PRIOR CC.PARENT_CODE_ID= CC.CODE_ID --此處PARENT_CODE_ID和CODE_ID順序受PRIOR影響  
  5. ;  

 SYS_CONNECT_BY_PATH : 和父結構名稱拼接圖片

SUBSTR : 去除最前面的大於號(>)字符串

CONNECT BY PRIOR :須要注意的是PRIOR 的順序

Sql代碼  
  1. CONNECT BY PRIOR CC.PARENT_CODE_ID= CC.CODE_ID  

 和

Java代碼  
  1. CONNECT BY CC.PARENT_CODE_ID= PRIOR  CC.CODE_ID  

 查詢出來的數據是不同。

上面sql查詢結果以下:



 

 查詢出來的數據爲3條是對的,但查詢出來的數據不能再進行第二次的過濾查詢,會報錯,如:

Sql代碼  
  1. SELECT * FROM (  
  2.     SELECT CC.*,SUBSTR(SYS_CONNECT_BY_PATH(CC.CODE_NAME,     '>'),2) TREE_PATH   
  3.     FROM CMM_CODE CC   
  4.     START WITH CC.Code_Id='pn_0501004'   
  5.     CONNECT BY PRIOR CC.PARENT_CODE_ID= CC.CODE_ID--此處    PARENT_CODE_ID和CODE_ID順序受PRIOR影響  
  6. TEMP WHER TEMPCODE_ID='pn_0500000'  
  7. ;  

 

 

 

並且查詢出來的結構順序是相反的,以下:

Java代碼  
  1. 特殊設施>公共服務設施>專業設施名稱  

 

方法二:使用WM_CONCAT函數進行拼接

Sql代碼  
  1. --TO_CHAR是爲了將clob轉成通常字符類型  
  2. --REPLACE是將逗號(,)改爲大於號(>)  
  3. --WM_CONCAT字符串拼接,默認是使用逗號(,)拼接  
  4. --查詢結果:專業設施名稱 > 公共服務設施 > 特殊設施  
  5. SELECT TO_CHAR(REPLACE(WM_CONCAT(TEMP.CODE_NAME), ',', ' > ')) TREE_PATH FROM(  
  6.   SELECT CC.*   
  7.   FROM CMM_CODE CC   
  8.   START WITH CC.Code_Id='pn_0501004'   
  9.   CONNECT BY PRIOR CC.PARENT_CODE_ID=CC.CODE_ID  
  10.   ORDER BY CC.ORDER_NUMBER  
  11. )TEMP   
  12. ;  

 查詢結果以下:

Java代碼  
  1. 專業設施名稱 > 公共服務設施 > 特殊設施  

 

結果順序正確,但同樣是不能關聯其它的表進行查詢。由於START WITH 後面必須加上具體的條件,不能使用關聯的的字段。

 

方式三:START WITH關聯查詢

Sql代碼  
  1. select info.*,  
  2. CC.CODE_NAME,SUBSTR(TEMP_TABLE.TREE_PATH, 4) TREE_PATH  
  3. from pn_place_name info   
  4. LEFT JOIN CMM_CODE CC ON CC.CODE_ID=INFO.CMM_CODE_ID  
  5. LEFT JOIN (  
  6.      SELECT code.*,SYS_CONNECT_BY_PATH(code.CODE_NAME, ' > ') TREE_PATH   
  7.     FROM CMM_CODE  code  
  8.     START WITH code.PARENT_CODE_ID IS NULL AND code.CLASS_CODE='PN_TYPE_NEW'  
  9.     CONNECT BY PRIOR code.CODE_ID= code.PARENT_CODE_ID  
  10. ) TEMP_TABLE ON TEMP_TABLE.CODE_ID=INFO.CMM_CODE_ID  
  11. where 1=1 and info.ISINSPECTOPINION is null   
  12. AND info.PN_NO='106737'  
  13. ;  

 SUBSTR(TEMP_TABLE.TREE_PATH, 4):去掉最前面的 空格 + 大於號(>)+ 空格

Java代碼  
  1. ' > '  

 

方法三和方法二的區別在於START WITH 後面的條件,和

CONNECT BY PRIOR code.CODE_ID= code.PARENT_CODE_ID

的條件,此處的順序是不同的。

 

方法三是把全部PARENT_CODE_ID IS NULL 的數據都取出來,即把最頂層的結構都先取出來,再去關聯子結構,取出來的數據是全部的。惟一的好處是能夠關聯其它表進行查詢。

 

結果:

知道具體的id值,而且是單條數據查詢,不須要關聯表時,使用方式二。

須要關聯表查詢時,使用方式三。

 

================================

©Copyright 蕃薯耀 2018年5月14日

https://www.cnblogs.com/fanshuyao/

相關文章
相關標籤/搜索