Hi, I have a table with three columns NodeId, ParentNodeId, NodeName. for each node I would like to get a full path like "lvl1/lvl2/lvl3..." where lvl1,lvl2 and lvl3 are node names. I found a function which does that at this link http://www.sql-server-helper.com/functions/get-tree-path.aspx. but I would like to use CTE OR any other technique for efficiency. Please let me know if it is possible to achieve this in a better way. Thanks in advance.
+3
A:
Here's a CTE version.
declare @MyTable table (
NodeId int,
ParentNodeId int,
NodeName char(4)
)
insert into @MyTable
(NodeId, ParentNodeId, NodeName)
select 1, null, 'Lvl1' union all
select 2, 1, 'Lvl2' union all
select 3, 2, 'Lvl3'
declare @MyPath varchar(100)
;with cteLevels as (
select t.NodeId, t.ParentNodeId, t.NodeName, 1 as level
from @MyTable t
where t.ParentNodeId is null
union all
select t.NodeId, t.ParentNodeId, t.NodeName, c.level+1 as level
from @MyTable t
inner join cteLevels c
on t.ParentNodeId = c.NodeId
)
select @MyPath = case when @MyPath is null then NodeName else @MyPath + '/' + NodeName end
from cteLevels
order by level
select @MyPath
Joe Stefanelli
2010-09-16 14:23:51
A:
The most efficient way, in my experience, would be to add an extra field, RootNodeID, containing the id of the toplevel node of the treestructure. So you can query all nodes in an entire treestructure in a very simple and efficient manner.
And to build that treestructure, a simple recursive function in your application should work just fine.
I know it's denormalization, and some people don't really approve of the concept, but I've learned in my professional experience that this brings a huge performance increase, as opposed to an elaborate t-sql script.
Joachim VR
2010-09-16 14:34:20
can u provide a simple code example for this please?
RKP
2010-09-16 14:51:59
What language would you like that in?
Joachim VR
2010-09-16 15:00:13
SQL Server Transact SQL
RKP
2010-09-16 15:01:42
Ah, but for the construction of the tree, I did mean recursive in the application language (c#, vb.net). Of course my solution won't work if you want it purely in SQL, without an application calling the query. If you have a fixed number of levels in your tree, the other solutions should work, else you could create a stored procedure, recursively calling itself.
Joachim VR
2010-09-16 15:17:45
A:
I solved it like this, much similar to Joe's solution.
with cte (NodeId,NodeName,hierarchyPath)as
(
select NodeId,NodeName, NodeName
from Node
where ParentNodeId is null
union all
select n.NodeId, n.NodeName, CONVERT(varchar(256), cte.hierarchyPath + '/' + n.NodeName)
from Node n
join cte on n.ParentNodeId = cte.NodeId
)
select *
from cte
order by NodeId
RKP
2010-09-16 15:00:55