来自树形式的自引用表的分层数据

时间:2010-05-12 21:33:23

标签: sql sql-server

看起来在所有简单的情况下都会被问到和回答,不包括那个我遇到麻烦的情况。我尝试过使用递归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

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

2 个答案:

答案 0 :(得分:8)

与邻接列表模式有关,但可以通过递归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列,这实际上是排序。

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