Using bottom-up or top-down search to find the best path from hierarchical data

谁说我不能喝 提交于 2019-12-13 07:23:53

问题


I have the following table structure,

Create Table Nodes
(
    NodeID int,
    ParentNodeID int, // null if root node
    NodeText nvarchar(100),
    NodeCost int
)

Now I need to do a sort of complex thing. Find the cost of the best path (path which has the best cost) from this table.

There are two ways, I am not sure which one to use:

  1. Bottom-up search: If I choose that, I need to add a isLeaf column to the table and use a CTE which does the job.
  2. Top-down search: There is no need of isLeaf field, however hard to come up with the SQL statement which does the job.

What are the pros and cons of the given two alternative methods? Which is the better practice in terms of performance etc.?


回答1:


I've wrote the answer before seeing it's no specified which RDBMS is used. This if for SQL Server, same or something similar should work in Postrge and Oracle, but not in MySQL.

Anyway, either way (Bottom-Up or Top-Down) is fine, and neither way you have to add isLeaf level column because you can simply find leaf level nodes with NOT IN or NOT EXISTS subquery - and you need that info in both ways if you are interested in only paths that go from top to bottom.

Here is a sample query for top-down search:

;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

Here is example for Bottom-Up:

;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

In this examples, performance of both queries are exactly the same. 50%-50% in execution plans when run together.



来源:https://stackoverflow.com/questions/16233946/using-bottom-up-or-top-down-search-to-find-the-best-path-from-hierarchical-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!