SQL Server 2008 CTE递归

tho*_*mas 6 sql common-table-expression sql-server-2008

我试图执行我认为使用CTE是SQL Server 2008的艰难递归.我似乎无法绕过这一个.

在下面的例子中,您可以假定固定深度为3 ......任何东西都不会低于此值.在现实生活中,深度"更深"但仍然固定.在这个例子中,我试图简化一些.

我的输入数据如下所示.

ID     PARENT_ID       NAME          DEPTH
------------------------------------------
1      NULL            A             1
2      1               B             2
3      2               C             3
4      1               D             2
Run Code Online (Sandbox Code Playgroud)

我的CTE的输出应该是下表.

LEVEL1_ID    LEVEL2_ID    LEVEL3_ID    LEVEL1_NAME    LEVEL2_NAME    LEVEL3_NAME
--------------------------------------------------------------------------------
1            NULL         NULL         A              NULL           NULL
1            2            NULL         A              B              NULL
1            2            3            A              B              C
1            4            NULL         A              D              NULL
Run Code Online (Sandbox Code Playgroud)

如果我可以在输出中获取ID列,我当然可以映射到查找表中的名称.

我也愿意采用其他方式来实现这一目标,包括使用SSIS.

mar*_*c_s 9

并非真的很难做到:

;WITH cte AS
(
    SELECT CAST('/' + Name AS VARCHAR(50)) as 'CteName', ID
    FROM dbo.YourTable
    WHERE parent_id IS NULL

    UNION ALL

    SELECT CAST(cte.CteName + '/' + Name AS VARCHAR(50)), t.ID
    FROM dbo.YourTable t
    INNER JOIN cte ON t.parent_id = cte.id
)
SELECT cteName FROM cte
ORDER BY ID
Run Code Online (Sandbox Code Playgroud)

给我一个输出:

/A
/A/B
/A/B/C
/A/D
Run Code Online (Sandbox Code Playgroud)

作为旁注:CTE可以很容易地计算出"深度",你不一定需要将它存储在你的表中(参见Level我添加的列):

;WITH cte AS
(
    SELECT 
       CAST('/' + Name AS VARCHAR(50)) as 'CteName', ID, 
       1 AS 'Level'
    FROM dbo.YourTable
    WHERE parent_id IS NULL

    UNION ALL

    SELECT 
       CAST(cte.CteName + '/' + Name AS VARCHAR(50)), t.ID,
       cte.Level + 1 AS 'Level'
    FROM dbo.YourTable t
    INNER JOIN cte ON t.parent_id = cte.id
)
SELECT cteName FROM cte
ORDER BY Level, ID
Run Code Online (Sandbox Code Playgroud)