【问题标题】:How do I combine multiple parent-child relationships with different lengths using T-SQL?如何使用 T-SQL 组合多个不同长度的父子关系?
【发布时间】:2019-05-21 16:25:09
【问题描述】:

总结

在 Azure 数据库中(使用 SQL Server Management Studio 17,因此 T-SQL)我试图连接多个不同长度的父子关系。

基表

我的桌子是这样的:

ID   parent
1    2
2    NULL
3    2
4    3
5    NULL

随意使用此代码来生成和填充它:

DECLARE @t TABLE (
ID int,
parent int
)

INSERT @t VALUES
( 1, 2 ),
( 2, NULL ),
( 3, 2 ),
( 4, 3 ),
( 5, NULL )

问题

我如何收到如下表所示路径连接的表格?

ID   path      parentcount
1    2->1      1
2    2         0
3    2->3      1
4    2->3->4   2
5    5         0

详情

真实的表有更多的行,最长的路径应该包含大约 15 个 ID。因此,在父计数定义方面找到一个动态的解决方案将是理想的。 另外:我不一定需要“parentcount”列,因此请随意跳过答案。

select @@version:
Microsoft SQL Azure (RTM) - 12.0.2000.8

【问题讨论】:

  • 看看递归 ctes。这正是您需要的。

标签: sql sql-server tsql ssms parent-child


【解决方案1】:

您可以为此使用递归 CTE:

with cte as (
      select id, parent, convert(varchar(max), concat(id, '')) as path, 0 as parentcount
      from @t t
      union all
      select cte.id, t.parent, convert(varchar(max), concat(t.id, '->', path)), parentcount + 1
      from cte join
           @t t
           on cte.parent = t.id
     )
select top (1) with ties *
from cte
order by row_number() over (partition by id order by parentcount desc);

【讨论】:

  • lev => parentcount?
  • @GSerg 。 . .那甚至不应该在那里。这是我用来调试以防止无限递归的东西。
  • 它在top (1) with ties * order by lev desc中使用。
【解决方案2】:

显然 Gordon 使用递归 CTE 解决了这个问题,但这里有另一个使用 HierarchyID 数据类型的选项。

示例

Declare @YourTable Table ([ID] int,[parent] int)  
Insert Into @YourTable Values 
 (1,2)
,(2,NULL)
,(3,2)
,(4,3)
,(5,NULL)

;with cteP as (
      Select ID
            ,Parent 
            ,HierID = convert(hierarchyid,concat('/',ID,'/'))
      From   @YourTable 
      Where  Parent is Null
      Union  All
      Select ID     = r.ID
            ,Parent = r.Parent 
            ,HierID = convert(hierarchyid,concat(p.HierID.ToString(),r.ID,'/'))
      From   @YourTable r
      Join   cteP p on r.Parent  = p.ID
)
Select ID
      ,Parent
      ,[Path]      = HierID.GetDescendant ( null , null ).ToString()   
      ,ParentCount = HierID.GetLevel() - 1
 From cteP A
 Order By A.HierID

退货

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-02
    • 2019-02-05
    • 2016-12-28
    • 1970-01-01
    • 2020-01-17
    • 2013-07-17
    • 1970-01-01
    • 2021-06-07
    相关资源
    最近更新 更多