有没有办法为SSMS中的递归CTE创建一个groupID?

问题描述

我正在构建一个查询,该查询输出数据库中每个根的所有权层次结构。我正在成功使用递归CTE,因为我目前可以实现以下数据输出:

rootID RootName RelatedName
1   ABA GPS
1   ABA PIG
1   ABA BBY
1   ABA PIG
2   PIG DDS
2   PIG GPS

我要实现的是一个组ID列,其中的数据可能如下所示:

GroupID rootID  RootName RelatedName
100    1    ABA GPS
100    1    ABA PIG
100    1    ABA BBY
100    1    ABA PIG
100    2    PIG DDS
100    2    PIG GPS

,同样对于组200、300等。每棵树。可以注入递归CTE的哪一部分来实现上述结果?

;WITH cte_Rel AS (
SELECT
<columns>
FROM #RawRel r 
WHERE 1 = 1
AND <initial Conditions>
UNION ALL 
SELECT
<Columns>
FROM #RawRel r
JOIN cte_Rel c ON r.RootName = c.RelatedName
) 
SELECT DISTINCT * FROM cte_Rel
OPTION (MAXRECURSION 100)

解决方法

您可以在回溯CTE的锚点部分添加行号。乘以100,然后在CTE的第二部分重复同一列。

Fiddle,以防您喜欢交互式代码。

样本数据

没有实际的查询和样本输入数据,很难完美地复制您的当前输出,因此我生成了自己的样本数据。

docker run -v $(pwd):<containerPathName>

解决方案

create table RelData
(
  ParentId int,Id int,Name nvarchar(3)
);

insert into RelData (ParentId,Id,Name) values
(null,1,'A00'),-- tree A
(1,2,'A10'),(2,3,'A11'),4,'A12'),(1,5,'A20'),(5,6,'A21'),(null,7,'B00'),-- tree B
(7,8,'B10'),(8,9,'B11');

结果

WITH cte_Rel AS (
  SELECT row_number() over(order by rd.Id) * 100 as TreeId,-- number to roots and multiply the root number by 100
         rd.Id,rd.Name,rd.ParentId,convert(nvarchar(3),null) as ParentName
  FROM RelData rd
  WHERE rd.ParentId is null
  
    UNION ALL
  
  SELECT c.TreeId,-- repeat the tree number
         rd.Id,c.name
  FROM RelData rd
  JOIN cte_Rel c ON rd.ParentId = c.Id
) 
SELECT c.TreeId,c.ParentId,c.ParentName,c.Name
FROM cte_Rel c
where c.ParentId is not null
order by c.ParentId;

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...