我已经写了答案,然后才看到它没有指定使用哪个RDBMS。如果对于SQL Server,相同或类似的应该在Postrge和Oracle中工作,但不在MySQL中。
无论如何,无论哪种方式(自下而上或自上而下)都不错,而且您也不需要添加isLeaf
级别的列,因为您可以简单地使用NOT IN或NOT EXISTS子查询找到叶级节点 - 而且您需要如果您只对从上到下的路径感兴趣,则可以通过两种方式获得信息。
这里是自上而下的搜索查询示例:
;WITH rCTE AS
(
SELECT NodeID ,
ParentNodeID ,
CAST(NodeID AS NVARCHAR(MAX)) AS PathIDs,
CAST(NodeText AS NVARCHAR(MAX)) AS PathText,
NodeCost AS PathCost
FROM Nodes WHERE ParentNodeID IS NULL
UNION ALL
SELECT n.NodeID ,
n.ParentNodeID ,
r.PathIDs + '-' + CAST(n.NodeID AS NVARCHAR(10)) AS PathIDs,
r.PathText + '-' + n.NodeText AS PathText,
r.PathCost + n.NodeCost AS PathCost
FROM rCTE r
INNER JOIN dbo.Nodes n ON n.ParentNodeID = r.NodeID
)
SELECT PathIDs ,
PathText ,
PathCost
FROM rCTE r
WHERE NOT EXISTS (SELECT * FROM Nodes n WHERE r.NodeID = n.ParentNodeID)
ORDER BY PathCost
这里是例如自下而上:
;WITH rCTE AS
(
SELECT NodeID ,
ParentNodeID ,
CAST(NodeID AS NVARCHAR(MAX)) AS PathIDs,
CAST(NodeText AS NVARCHAR(MAX)) AS PathText,
NodeCost AS PathCost
FROM Nodes r WHERE NOT EXISTS (SELECT * FROM Nodes n WHERE r.NodeID = n.ParentNodeID)
UNION ALL
SELECT n.NodeID ,
n.ParentNodeID ,
r.PathIDs + '-' + CAST(n.NodeID AS NVARCHAR(10)) AS PathIDs,
r.PathText + '-' + n.NodeText AS PathText,
r.PathCost + n.NodeCost AS PathCost
FROM rCTE r
INNER JOIN dbo.Nodes n ON r.ParentNodeID = n.NodeID
)
SELECT PathIDs ,
PathText ,
PathCost
FROM rCTE r
WHERE r.ParentNodeID IS NULL
ORDER BY PathCost
SQLFiddle DEMO - Top-Down
SQLFiddle DEMO - Bottom-Up
在这个例子中,两个查询的性能完全相同。一起运行时执行计划中的50%-50%。
您使用的是什么RDBMS? – 2013-04-26 10:43:33
MSSQL Server 2008 – Sait 2013-04-26 11:08:14