SQL Server最后一个节点

时间:2016-03-12 13:28:09

标签: sql-server recursion

我在SQL Server中有以下表格:

| id | Name    | ParentId |    
| 1  | world   | Null     |
| 2  | Region  | 1        |
| 3  | Country | 2        |
| 4  | State   | 3        |
| 5  | City    | 4        |
| 6  | Street  | 5        |

层次结构的数量不固定。

我需要以街道,城市,州,国家,地区,世界的形式输出。

运行以下SQL代码:

WITH Hierarchy (ChildId, ChildName, ParentId, Childs) AS
(
    SELECT 
        Id, Name, ParentId, CAST('' AS VARCHAR(MAX))
    FROM 
        UserType AS LastGeneration
    WHERE 
        Id NOT IN (SELECT COALESCE(ParentId, 0) FROM UserType)  

    UNION ALL

    SELECT 
        PrevGeneration.Id, PrevGeneration.Name, PrevGeneration.ParentId,
        CAST(CASE WHEN Child.Childs = ''
                     THEN(CAST(Child.ChildName AS VARCHAR(MAX)))
                     ELSE(Child.Childs + ', ' + CAST(Child.ChildName AS VARCHAR(MAX)))
        END AS VARCHAR(MAX))
    FROM 
        UserType AS PrevGeneration
    INNER JOIN 
        Hierarchy AS Child ON PrevGeneration.Id = Child.ParentId  
)
SELECT *
FROM Hierarchy
OPTION(MAXRECURSION 32767)

返回输出:

Street, City, State, Country, Region

我需要在递归中添加什么来获取最后一个节点?

提前致谢!

1 个答案:

答案 0 :(得分:0)

两种不同的解决方案 - 一种是自上而下,另一种是自下而上。自上而下的解决方案更有效率。我不确定你想要什么输出中间行,所以我发布了两个。

DECLARE @usertype TABLE
(id int, Name varchar(20),ParentId int)

INSERT @usertype
VALUES (1 ,'world',Null),(2 ,'Region',1),(3 ,'Country',2),  
(4 ,'State',3), (5 ,'City',4),(6 ,'Street',5);   


-- Top down
WITH recCTE
AS
(
    SELECT Id, Name, ParentId, CAST(Name AS VARCHAR(MAX)) AS name_hierarchy
    FROM @UserType
    WHERE ParentId IS NULL

    UNION ALL

    SELECT u.Id, u.name, u.ParentId, u.name + ', ' + r.name_hierarchy
    FROM recCTE AS r
    JOIN @usertype AS u
    ON u.ParentId = r.Id
)
SELECT * FROM recCTE;

--Bottom up
WITH recCTE2
AS
(
    SELECT Id, Name, ParentId, CAST(Name AS VARCHAR(MAX)) AS name_hierarchy
    FROM @usertype AS u1
    WHERE NOT EXISTS (SELECT * FROM @usertype AS u2 WHERE u1.Id = u2.ParentId)

    UNION ALL

    SELECT u.Id, u.name, u.ParentId,  r.name_hierarchy+ ', ' + u.name 
    FROM recCTE2 AS r
    JOIN @usertype AS u
    ON r.ParentId = u.Id
)
SELECT * FROM recCTE2;

根据您发布的信息,您的代码有一些额外的复杂性,这似乎是不必要的。