我目前有一个看起来像这样的表:
| 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_URN 901,902和906 B_URN 901,902和906还包含A_URN 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 :(得分: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