获取包含sql server中所有子记录的记录

时间:2013-04-16 07:19:24

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

我在sql server中有heirrchical数据。 Follwing是我的数据heirarcy树。

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查询,找出包含从父项到其所有包含子项的所有记录的路径。

提前致谢。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

请尝试:

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