# Oracle查詢樹狀結構資料(遞迴) ###### tags: `ORACLE` `CONNECT BY` - [name=Felix Hsieh] - [time=Thu, May 26, 2022 1:16 AM] --- ## 實作 Part.1 (反序搜尋) ```sql= SELECT Product_Category_NO , LPAD(' ', (LEVEL - 1) * 4) || Product_Category_Name AS PartName --自動縮排,每次4個[space] , SYS_CONNECT_BY_PATH(Product_Category_Name,'/') AS PartPath --自動組裝路徑,以 / 作為分隔符號 , LEVEL AS "LEVEL" --遞迴的層數 FROM Product_Category_Table START WITH Product_Category_NO = '123456' --遞迴搜尋的[起點] CONNECT BY PRIOR Parent_Category_NO = Product_Category_NO; --以CONNECT BY 定義主從關係,父項欄位前要加上PRIOR ``` ### 執行結果 | Product_Category_NO | PartName | PartPath | LEVEL | | ------------------- | ------------ | --------------------------- | ----- | | 12 | 台北市 | /研究院路一段/南港區/台北市 | 3 | | 1234 | 南港區 | /研究院路一段/南港區 | 2 | | 123456 | 研究院路一段 | /研究院路一段 | 1 | >從上表可以看到,由於我們的資料若是是由後往前做查詢,那出來的資料就會是反向的... > >這個可能跟我們想要的結果不符 > >所以… ## 實作 Part.2 (反轉結果) ```sql=+ SELECT Product_Category_NO , LPAD(' ', (LEVEL - 1) * 4) || sub_path AS PartName --自動縮排,每次4個[space] , SYS_CONNECT_BY_PATH(sub_path, '/') AS PartPath --自動組裝路徑,以 / 作為分隔符號 , LEVEL AS "LEVEL" --遞迴的層數 FROM ( SELECT Product_Category_NO , Product_Category_Name AS sub_path , LEVEL AS "RK" --遞迴的層數 FROM Product_Category_Table START WITH Product_Category_NO = '123456' --遞迴搜尋的[起點] CONNECT BY PRIOR Parent_Category_NO = Product_Category_NO --以CONNECT BY 定義主從關係,父項欄位前要加上PRIOR ) CONNECT BY PRIOR RK - 1 = RK START WITH RK = (6); --因為這邊是要逆向搜尋,所以這邊要填入的是最大的階層數 ``` ### 執行結果 | Product_Category_NO | PartName | PartPath | LEVEL | | ------------------- | ------------ | --------------------------- | ----- | | 12 | 台北市 | /台北市 | 1 | | 1234 | 南港區 | /台北市/南港區 | 2 | | 123456 | 研究院路一段 | /台北市/南港區/研究院路一段 | 3 | >如此以來...若碰到需要反向搜尋時,這就會是我們需要的結果了.. > >若只是需要取用最後一筆的PartPath的話… > >加個MAX()就行了,如下.... ## 實作 Part.3 (收納) ```sql=+ SELECT MAX(SYS_CONNECT_BY_PATH(sub_path, '/')) AS PartPath --自動組裝路徑,以 / 作為分隔符號 FROM ( SELECT Product_Category_NO , Product_Category_Name AS sub_path , LEVEL AS "RK" --遞迴的層數 FROM Product_Category_Table START WITH Product_Category_NO = '123456' --遞迴搜尋的[起點] CONNECT BY PRIOR Parent_Category_NO = Product_Category_NO --以CONNECT BY 定義主從關係,父項欄位前要加上PRIOR ) CONNECT BY PRIOR RK - 1 = RK START WITH RK = (6); --因為這邊是要逆向搜尋,所以這邊要填入的是最大的階層數 ``` ### 執行結果 |PartPath| | - | |/台北市/南港區/研究院路一段|