Sql 这个结果可以通过递归cte实现吗?
我当前有一个如下所示的表:Sql 这个结果可以通过递归cte实现吗?,sql,recursion,common-table-expression,Sql,Recursion,Common Table Expression,我当前有一个如下所示的表: | A_URN | B_URN | ID | |-------|-------|----| | 101 | 901 | 0 | |-------|-------|----| | 102 | 901 | 0 | |-------|-------|----| | 101 | 902 | 0 | |-------|-------|----| | 102 | 902 | 0 | |-------|-------|----| | 201
| 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 |
我需要添加一个标识符,将所有相关项目分组在一起
例如,骨灰盒101连接到骨灰盒901、902和906,并且
骨灰盒901、902和906还包含骨灰盒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或groupby,这是不允许的
是否可以使用递归查询获得此类结果?如果需要使用递归CTE的MSSQL解决方案。以下是一个适用于您的案例的查询:
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
如果您需要使用递归CTE的MSSQL解决方案。以下是一个适用于您的案例的查询:
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
你能用while循环发布解决方案吗?你用什么关系数据库(MSSQL,Oracle)?你能用while循环发布解决方案吗?你用什么关系数据库(MSSQL,Oracle)?