【问题标题】:Is there a way to create a groupID for a recursive CTE in SSMS?有没有办法在 SSMS 中为递归 CTE 创建 groupID?
【发布时间】:2020-09-23 15:22:01
【问题描述】:

我正在构建一个查询,该查询输出数据库中每个根的所有权层次结构。我正在成功使用递归 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)

【问题讨论】:

  • GroupID的值从何而来?既然都是一样的值,何不简单的100 AS GroupID
  • 我的数据中会有多棵树...所以在上面的演示中,CTE 将生成这棵树 100,但也可能有其他树需要它们自己的 groupID。
  • 所以我需要在这个 CTE 或其他东西中采用巧妙的递增策略......

标签: ssms hierarchical-data recursive-cte


【解决方案1】:

您可以将行号添加到递归 CTE 的锚部分。乘以 100 并在 CTE 的第二部分重复同一列。

Fiddle 如果您更喜欢交互式代码。

样本数据

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

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'),
(2,    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, rd.Name, rd.ParentId, 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;

结果

TreeId ParentId ParentName Name
------ -------- ---------- ----
100    1        A00        A10
100    1        A00        A20
100    2        A10        A11
100    2        A10        A12
100    5        A20        A21
200    7        B00        B10
200    8        B10        B11

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-19
    • 2019-07-04
    • 2013-04-14
    • 2020-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多