Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 这个结果可以通过递归cte实现吗?_Sql_Recursion_Common Table Expression - Fatal编程技术网

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)?