获取TSQL层次结构路径

时间:2018-06-05 16:49:00

标签: sql sql-server sql-server-2012

代码w / my try

DECLARE @T TABLE
    (
        [Id]        BIGINT
      , [Value]     NVARCHAR(MAX)
      , [Parent_Id] BIGINT
    ) ;
INSERT  @T
VALUES
    ( 1, N'A', NULL )
  , ( 2, N'B', 1 )
  , ( 3, N'C', 2 )
  , ( 4, N'D', 1 )
  , ( 5, N'E', NULL )
  , ( 6, N'F', 5 )
  , ( 7, N'G', 5 )
  , ( 8, N'H', 7 ) ;

; WITH [CTE] AS
    (
        SELECT  [Id]
              , [Value]
              , [Parent_Id]
              , CAST ( [Value] AS NVARCHAR(MAX) ) AS [ValuePath]
        FROM    @T
        --WHERE   [Id] = 3
        UNION ALL
        SELECT  [P].[Id]
              , [P].[Value]
              , [P].[Parent_Id]
              , CAST ( CONCAT ( [C].[ValuePath], N' > ', [P].[Value] ) AS NVARCHAR(MAX) ) AS [ValuePath]
        FROM    @T    AS [P]
        JOIN    [CTE] AS [C]
        ON      [P].[Parent_Id] = [C].[Id]
    )
SELECT      *
FROM        [CTE]
ORDER BY    [CTE].[Id]
OPTION ( MAXRECURSION 0 ) ;

当前输出

Id  Value   Parent_Id   ValuePath
1   A   NULL    A
2   B   1   B
2   B   1   A > B
3   C   2   B > C
3   C   2   A > B > C
3   C   2   C
4   D   1   D
4   D   1   A > D
5   E   NULL    E
6   F   5   F
6   F   5   E > F
7   G   5   E > G
7   G   5   G
8   H   7   H
8   H   7   G > H
8   H   7   E > G > H

期望的输出 没有过滤器时

Id  Value   Parent_Id   ValuePath
1   A       NULL        A
2   B       1           A > B
3   C       2           A > B > C
4   D       1           A > D
5   E       NULL        E
6   F       5           E > F
7   G       5           E > G
8   H       7           E > G > H

使用过滤器(例如Id = 3)

Id  Value   Parent_Id   ValuePath
3   C       2           A > B > C

目标 使用"获取Value字段的路径> "分隔符。可以应用可选的Id过滤器。我获得了所有记录,但每个Id及其完整路径只需要1条记录。此外,性能很重要。你会建议我用过滤器创建一个udf吗?如果您需要更多信息,请告诉我。我

1 个答案:

答案 0 :(得分:3)

将查询更改为此将返回所需的输出:

;WITH [CTE] ([Id], [Value], [Parent_Id], [ValuePath]) AS
(
    SELECT [Id], 
           [VALUE], 
           [Parent_Id], 
           [Value]
    FROM @T
    WHERE [Parent_Id] IS NULL
    UNION ALL
    SELECT [n].[Id], 
           [n].[Value], 
           [n].[Parent_Id], 
           CONVERT(NVARCHAR(MAX), [CTE].[ValuePath] + ' > ' + [n].[Value])
    FROM @T [n] INNER JOIN [CTE] ON [n].[Parent_Id] = [CTE].[Id]
)
SELECT * 
FROM [CTE]
ORDER BY [Id]