2010-05-12 19 views
3

看起来这个问题已经在所有简单的例子中被提出并回答过,不包括我遇到的问题。我试过使用递归CTE来生成这个;不过也许游标会更好?或者,也许一组递归函数可以做到这一点?树形自回参考表的分层数据

这可以在cte中完成吗?

考虑下表

PrimaryKey ParentKey 
1   NULL  
2   1  
3   6 
4   7 
5   2 
6   1 
7   NULL 

应该产生

PK 
1 
-2 
--5 
-6 
--3 
7 
-4 

其中的数 - 标记等于深度,我的主要困难是排序。

回答

7

这是一种kludgey与邻接表的模式做的,但它可以用递归CTE来完成:

WITH Hierarchy AS 
(
    SELECT 
     PrimaryKey, ParentKey, 
     CAST('/' + CAST(PrimaryKey AS varchar(10)) AS varchar(50)) AS [Path], 
     CAST('' AS varchar(50)) AS Prefix 
    FROM @Tbl 
    WHERE ParentKey IS NULL 

    UNION ALL 

    SELECT 
     t.PrimaryKey, t.ParentKey, 
     CAST(h.[Path] + '/' + CAST(t.PrimaryKey AS varchar(10)) AS varchar(50)), 
     CAST(h.Prefix + '-' AS varchar(50)) 
    FROM Hierarchy h 
    INNER JOIN @Tbl t 
     ON t.ParentKey = h.PrimaryKey 
) 
SELECT [Path], Prefix + CAST(PrimaryKey AS varchar(10)) AS Node 
FROM Hierarchy 
ORDER BY [Path] 

为了得到你想要的确切结果,你既需要Prefix列(其中不“缩进”)和代理Path列,它实际上是排序。

+0

不错的工作。感谢您的解决方案。 – 2013-01-08 03:56:52

1

这是我的产品 - 如果需要,您还可以获取每个节点的路径。更改str(x,4)调用 - 使其转换为十进制时,使主键的最大长度为4。

WITH TreePrinter(id, parent, path, prefix) AS 
(
    SELECT 
     PrimaryKey, ParentKey, 
     CAST(str(PrimaryKey,4) AS varchar(max)), 
     CAST('' AS varchar(max)) 
    FROM YourTable 
    WHERE ParentKey IS NULL 
    UNION ALL 
    SELECT child.PrimaryKey, child.ParentKey, 
    CAST(parent.path+'/'+STR(child.PrimaryKey,4) AS varchar(max)), 
    CAST(parent.prefix+'-' AS varchar(max)), 
    FROM YourTable parent 
    INNER JOIN TreePrinter child ON child.id=parent.ParentKey 
) 
SELECT prefix+str(id) FROM TreePrinter 
ORDER BY path