2016-12-01 104 views
1

我現在有一個表,看起來像這樣:這個結果可以通過遞歸cte來實現嗎?

| A_URN | B_URN | ID | 
|-------|-------|----| 
| 101 | 901 | 0 | 
|-------|-------|----| 
| 102 | 901 | 0 | 
|-------|-------|----| 
| 101 | 902 | 0 | 
|-------|-------|----| 
| 102 | 902 | 0 | 
|-------|-------|----| 
| 201 | 902 | 0 | 
|-------|-------|----| 
| 201 | 903 | 0 | 
|-------|-------|----| 
| 202 | 903 | 0 | 
|-------|-------|----| 
| 301 | 904 | 0 | 
|-------|-------|----| 
| 302 | 904 | 0 | 
|-------|-------|----| 
| 301 | 905 | 0 | 
|-------|-------|----| 
| 302 | 905 | 0 | 
|-------|-------|----| 
| 303 | 905 | 0 | 
|-------|-------|----| 
| 101 | 906 | 0 | 

我需要添加一個標識符,組中的所有相關項目放在一起。

例如A_URN 101連接到B_URNs 901,902,以及906和 B_URNs 901,902和906還包含A_URNs 102和201

A_URN 201也被連接到B_URN 903等等,等等

最終的結果應該是這個樣子:

| A_URN | B_URN | ID | 
|-------|-------|----| 
| 101 | 901 | 1 | 
|-------|-------|----| 
| 102 | 901 | 1 | 
|-------|-------|----| 
| 101 | 902 | 1 | 
|-------|-------|----| 
| 102 | 902 | 1 | 
|-------|-------|----| 
| 201 | 902 | 1 | 
|-------|-------|----| 
| 201 | 903 | 1 | 
|-------|-------|----| 
| 202 | 903 | 1 | 
|-------|-------|----| 
| 301 | 904 | 2 | 
|-------|-------|----| 
| 302 | 904 | 2 | 
|-------|-------|----| 
| 301 | 905 | 2 | 
|-------|-------|----| 
| 302 | 905 | 2 | 
|-------|-------|----| 
| 303 | 905 | 2 | 
|-------|-------|----| 
| 101 | 906 | 1 | 

我寫了實現這一使用while()循環查詢,但都被要求返工它變成一個遞歸CTE。 我試過了,但總是最終需要在遞歸成員中使用MIN或GROUP BY,這是不允許的。

使用遞歸查詢有可能得到這種結果嗎?

+0

您可以發佈與while循環的解決方案? – artm

+0

您使用的是什麼RDBMS(MSSQL,Oracle)? – valex

回答

0

如果您需要遞歸CTE的MSSQL解決方案。下面是一個查詢from my answer to the similar question適合於您的情況:

WITH T as 
(
    SELECT A_URN,B_URN, ROW_NUMBER() OVER (ORDER BY A_URN) as ID FROM Table14 
) 
,CTE AS 
(
    SELECT CAST(','+CAST(A_URN AS Varchar(100)) +','+ CAST(B_URN as Varchar(100))+',' as Varchar(MAX)) as GroupCont, 
     id 
    FROM T 
    UNION ALL 
    SELECT CAST(GroupCont+CAST(A_URN AS Varchar(100)) +','+ CAST(B_URN as Varchar(100))+',' AS Varchar(MAX)) as GroupCont, 
     pm.id 
    FROM CTE 
    JOIN T as pm 
    ON 
    (
     CTE.GroupCont LIKE '%,'+CAST(pm.A_URN AS Varchar(100))+',%' 
     OR 
     CTE.GroupCont LIKE '%,'+CAST(pm.B_URN AS Varchar(100))+',%' 
    ) 
    AND NOT 
    (
     CTE.GroupCont LIKE '%,'+CAST(pm.A_URN AS Varchar(100))+',%' 
     AND 
     CTE.GroupCont LIKE '%,'+CAST(pm.B_URN AS Varchar(100))+',%' 
    ) 
), 
T1 AS 
(
SELECT pm.A_URN, 
     pm.B_URN, 
     ISNULL(
     (SELECT MAX(ID) FROM CTE WHERE 
     (
      CTE.GroupCont LIKE '%,'+CAST(pm.A_URN AS Varchar(100))+',%' 
      OR 
      CTE.GroupCont LIKE '%,'+CAST(pm.B_URN AS Varchar(100))+',%' 
     )) 
     ,pm.ID) as ID 
FROM T pm 
) 

SELECT A_URN,B_URN, 
     DENSE_RANK() OVER (ORDER BY ID) AS ID 
FROM T1 
ORDER BY B_URN,A_URN