看起来在所有简单的情况下都会被问到和回答,不包括那个我遇到麻烦的情况。我尝试过使用递归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
其中 - 标记的数量等于深度,我的主要难点是排序。
答案 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