【问题标题】:Get records containing all the child records in sql server获取包含sql server中所有子记录的记录
【发布时间】:2013-04-08 12:01:48
【问题描述】:

我在 sql server 中有分层数据。 以下是我的数据继承树。

Id      Name         ParentID

1124    ABC          2
1125    BCD          1124
1126    EFG          1124   
1127    HIJ          1126   
1128    KLM          1126
1129    OPQ          1124   
1130    RST          1124
1131    UVW          1130
1132    XYZ          1131
1133    ZYA1         1124

现在我想要上表的以下结果。在那我想要从根(父)与所有孩子到最后一个孩子的路径。

Id      Name    ParentID    PATH

1124    ABC     2           ABC
1125    BCD     1124        ABC/BCD
1126    EFG     1124        ABC/EFG
1127    HIJ     1126        ABC/EFG/HIJ
1128    KLM     1126        ABC/EFG/KLM
1129    OPQ     1124        ABC/OPQ
1130    RST     1124        ABC/RST
1131    UVW     1130        ABC/RST/UVW
1132    XYZ     1131        ABC/RST/UVW/XYZ
1133    ZYA1    1124        ABC/ZYA1

那么任何人都可以帮助我编写 sql 查询以找出包含从父项到所有包含子项的所有记录的路径。

提前致谢。

【问题讨论】:

    标签: sql sql-server-2008 parent-child common-table-expression


    【解决方案1】:

    请尝试:

    DECLARE @table as TABLE(Id INT, [Name] NVARCHAR(50), ParentID INT)
    
    insert into @table values
    (1124, 'ABC', 2),
    (1125, 'BCD', 1124),
    (1126, 'EFG', 1124),
    (1127, 'HIJ', 1126), 
    (1128, 'KLM', 1126),
    (1129, 'OPQ', 1124), 
    (1130, 'RST', 1124),
    (1131, 'UVW', 1130),
    (1132, 'XYZ', 1131),
    (1133, 'ZYA1', 1124)
    
    ;WITH parent AS
    (
        SELECT *, convert(nvarchar(max), [Name]) as [Path] from @table WHERE ParentID = 2
        UNION ALL 
        SELECT t.*, convert(nvarchar(max), parent.[Path]+'\'+t.[Name]) as [Path]
        FROM parent
        INNER JOIN @table t ON t.parentid =  parent.id
    )SELECT * FROM parent
    ORDER BY ID
    

    【讨论】:

      【解决方案2】:

      您需要使用递归公用表表达式,然后仅过滤每条记录的基本路径的结果(即,对于 ID 1131,获取 ABC/RST/UVW 而不仅仅是 ABC/RST

      WITH CTE AS
      (   SELECT  ID, 
                  Name, 
                  ParentID, 
                  NextParentID = ParentID, 
                  Path = CAST(Name AS VARCHAR(MAX)),
                  Recursion = 1
          FROM    T
          UNION ALL
          SELECT  CTE.ID, 
                  CTE.Name, 
                  CTE.ParentID, 
                  T.ParentID, 
                  CAST(T.Name + '/' + CTE.Path AS VARCHAR(MAX)),
                  Recursion + 1
          FROM    CTE
                  INNER JOIN T
                      ON CTE.NextParentID = T.ID
      ), CTE2 AS
      (   SELECT  CTE.ID,
                  CTE.Name,
                  CTE.ParentID,
                  CTE.Path,
                  RowNumber = ROW_NUMBER() OVER(PARTITION BY CTE.ID ORDER BY Recursion DESC)
          FROM    CTE
      )
      SELECT  ID, Name, ParentID, Path
      FROM    CTE2
      WHERE   RowNumber = 1;
      

      Example on SQL Fiddle

      【讨论】:

      • ,我运行了这个查询,但它给了我错误“递归查询“CTE”的“路径”列中的锚点和递归部分之间的类型不匹配。”
      • 我添加了进一步的 CAST 以确保类型一致。
      • 伟大的@GarethD。它的工作并得到我正在寻找的东西。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-08
      • 1970-01-01
      • 2016-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多