【发布时间】:2012-04-23 02:44:31
【问题描述】:
我可以通过使用 SQL Server 的 With 命令 (CTE) 来实现递归。
WITH MyCTE(ParentID,ID,Name,Level)
AS
(
SELECT ManagerID AS ParentID, UserID AS ID, UserName AS Name, 0 AS Level
FROM USERS U
WHERE U.ManagerID IS NULL
UNION ALL
SELECT U.ManagerID AS ParentID, U.UserID AS ID, U.UserName AS Name, H.Level+1 AS Level
FROM USERS U
INNER JOIN MyCTE H ON H.ID = U.ManagerID
)
SELECT ParentID,ID FROM MyCTE
返回
ParentID ID
NULL 1
1 2
1 3
2 4
我想要实现的是反转这个结果集。即把根节点和最深的子节点反转为,
ParentID ID
NULL 4
4 2
2 1
3 1
无法弄清楚如何以编程方式实现这一点(最好使用 CTE),例如使用参数来确定递归顺序等。非常感谢任何帮助,谢谢。
编辑:
修改了这一点,将我的第一个 CTE 的结果插入到临时表中,然后使用另一个递归我将顺序反转为(我知道“WHERE T.ID = (SELECT MAX(ID) FROM @tmp)”不会在实际情况,我还得用“Level”列确定最深的节点,只是为了简化这个例子),
INSERT INTO @tmp
SELECT ParentID,ID,Level FROM MyCTE
WITH MyCTE2(ParentID,ID,Level)
AS
(
SELECT NULL AS ParentID, ID AS ID, 0 AS Level FROM @tmp T
WHERE T.ID = (SELECT MAX(ID) FROM @tmp)
UNION ALL
SELECT R2.ID AS ParentID, T.ParentID AS ID, R2.Level+1 FROM @tmp T
INNER JOIN MyCTE2 R2 ON R2.ID = T.ID
WHERE T.ParentID IS NOT NULL
)
原始结果(删除了 1,3 对)
ParentID ID Level
NULL 1 0
1 2 1
2 4 2
反转结果,
ParentID ID Level
NULL 4 0
4 2 1
2 1 2
编辑 2:
我做了这样的事情,
SELECT TTT.ParentID,TTT.ID,TTT.Level FROM
(
SELECT ParentID,ID,Level FROM MyCTE2
UNION ALL
SELECT TT.ID AS ParentID,TT.ParentID AS ID,(SELECT Level+1 FROM @tmp WHERE ID=TT.ID)
AS Level FROM
(
SELECT ID FROM @tmp
EXCEPT
SELECT ID FROM MyCTE2
)T INNER JOIN @tmp TT ON TT.ID = T.ID
)TTT
ORDER BY TTT.Level
给予,
ParentID ID Level
NULL 4 0
4 2 1
2 1 2
3 1 2
这可能包含错误,我还不确定,只是想显示以确保 (3,1) 对与级别 2 是否正确?想了很久,可能会犯一些愚蠢的错误。
【问题讨论】:
-
@MartinSmith 这不起作用仔细阅读帖子。
-
@MartinSmith 以相反的顺序重新创建层次结构。
-
您需要先构建层次结构,因此基本上在您现有的 CTE 之后添加另一个 CTE 以向后退。如果不先构建树,就无法知道某事物的深度。
-
也许包括提供你的样本结果的样本数据会帮助那些试图帮助你的人。
-
@OzanYukruk - 明确定义他们想要什么。这个问题很难思考,更别说回答了。并以最终没有意义的方式回答它。
标签: sql-server recursion common-table-expression with-statement