sql中的遞歸拼接


DB2遞歸實現字符串分組連接操作

 

db2中的遞歸查詢使用with來實現,也稱為公共表達式,公共表達式在select語句的開始部分采用with子句的形式,在使用公共表達式的查詢中可以多次使用它,並且公共表達式還可以通過取別名來連接到他本身,這樣的話就可以達到循環的目的。

 

遞歸查詢通常有3個部分需要定義:

 

一:一個公共表達式形式的虛擬表。

二:一個初始化表。

三:一個與虛擬表進行完全內連接的輔助表。

 

需要使用UNION all合並上邊3個查詢,然后用select從遞歸輸出中得到最終的結果。

 

大體上如下形式

with XX(x1,x2,x3) as  -------@0

(

select a.s,a.s1 from a  ----@1

union all  ----@2

select * from a,xx where a.s=xx.x1 ------@3

)

select ... from xx where .... -------@4

 

@0:為with體,即虛擬表

@1:為初始化表,這里需要定義初始化的一些行,也就是你遞歸的出發點,或者說父行,這部分邏輯只執行一次,它的結果作為虛擬表遞歸的初始化內容。

@2:這里必須用UNION all

@3:這里需要定義遞歸的條件(輔助表),這里定義遞歸的邏輯,需要注意的是父行和子行進行連接的時候邏輯一定要清楚父子關系,不然很容易變成死循環的,這里首先將初始化表的結果作為條件進行查詢,在把執行的結果添加到虛擬表中,只要這里能查詢出來記錄,那么就會進行下一步遞歸循環。

@4:這里就是對虛擬表的查詢語句。

 

需求:一張實時表,一個人每到一個地方,就有一條記錄存在,存放樣例:

張三 上海

張三 杭州

.....

要求,按人名進行匯總,將他到過的地方拼接,中間用'#'分隔

數據准備:

--創建表:

CREATE TABLE Recursive_Test

(User_Name VARCHAR(12),

 City VARCHAR(12));

--數據插入

INSERT INTO Recursive_Test(User_Name,City)

      values ('張三','杭州'),('張三','鄭州'),('李四','杭州'),

             ('張三','南昌'),('李四','廣州'),('王五','北京');

-----遞歸實現:

WITH Recursive_Test_Par(User_Name,City,Rk_Num) as(

SELECT User_Name,City,ROW_NUMBER() OVER(PARTITION BY User_Name) --分組,生成序列,自我關聯之用

FROM Recursive_Test

),

City_Join(User_Name,City,R_Num) as(

SELECT User_Name,CAST(City AS VARCHAR(100)),Rk_Num from Recursive_Test_Par WHERE Rk_Num=1

UNION ALL

SELECT a1.User_Name,CAST(a1.City||'#'||b1.City AS VARCHAR(100)),a1.R_Num+1

  from City_Join a1,Recursive_Test_Par b1

WHERE a1.User_Name=b1.User_Name and a1.R_Num=b1.Rk_Num-1

SELECT a.User_name,a.City FROM City_Join a INNER JOIN

      (SELECT User_Name,max(R_Num) R_Num from City_Join

       GROUP BY User_Name) b

ON a.User_name=b.User_name and a.R_Num=b.R_Num;

 --結果:

 

王五

北京

李四

杭州#廣州

張三

杭州#鄭州#南昌

 

 

 

實戰例子

表說明

ID        巡檢組ID     INTEGER

NAME     巡檢組名稱

HYPO     父節點ID, ID=-1 為根節點

TYPE      =0 是葉子節點 值=1是非葉子節點

ID          HYPO        NAME                                                                                                                                    TYPE       
----------- ----------- --------------------------------------------------------------------------------------------------------------------------------------- -----------
          1          -1 cisco                                                                                                                                            -1
          8           1 交換機巡檢                                                                                                                                        0
        429           1 思科設備端口巡檢                                                                                                                                  0
        469          -1 huawei                                                                                                                                           -1
        470         469 交換機                                                                                                                                            0
        471         469 huawei-1                                                                                                                                         -1
        472         471 huawei-1-1                                                                                                                                       -1
        473         472 路由器                                                                                                                                            0

 

 

sql:

db2 "
    with rpl (ID,HYPO,NAME,TYPE) AS
    (
        SELECT ID,HYPO,NAME,TYPE FROM T_CHECK_GROUP WHERE HYPO =-1
        UNION ALL
        SELECT child.ID,child.HYPO,CAST(parent.NAME||'~'||child.NAME AS VARCHAR(100)) ,child.TYPE from rpl parent,T_CHECK_GROUP child WHERE parent.ID=child.HYPO 
    )
    select ID,NAME from rpl where TYPE =0"

res:

          8 cisco~交換機巡檢                                                                  
        429 cisco~思科設備端口巡檢                                                            
        470 huawei~交換機                                                                     
        473 huawei~huawei-1~huawei-1-1~路由器  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM