-- DROP TABLE #tblAsset;CREATE TABLE #tblAsset(ID int IDENTITY(1,1),AssetID bigint,ParentID bigint,Asset varchar(90),Node int);INSERT INTO #tblAsset(AssetID, ParentID,Asset,Node)VALUES(3319,3214,'Apartment',1);INSERT INTO #tblAsset(AssetID, ParentID,Asset,Node) VALUES( 3320,3319,'Building 1508',2);INSERT INTO #tblAsset(AssetID, ParentID,Asset,Node) VALUES( 3321,3319,'Building 1509',2);INSERT INTO #tblAsset(AssetID, ParentID,Asset,Node) VALUES( 3322,3319,'Building 1510',2);INSERT INTO #tblAsset(AssetID, ParentID,Asset,Node) VALUES(3323,3320,'Room 210',3);INSERT INTO #tblAsset(AssetID, ParentID,Asset,Node) VALUES( 3324,3320,'Room 211',3);WITH cteBuildPath AS (--==== This is the "anchor" part of the recursive CTE SELECT anchor.AssetID, anchor.ParentID, anchor.Asset, anchor.Node, 1 AS HLevel, CAST(CAST(anchor.AssetID AS BINARY(4)) AS VARBINARY(8000)) AS SortPath FROM #tblAsset AS anchor WHERE Node = 1 UNION ALL ------------------------------------------------------------------- --==== This is the "recursive" part of the CTE that adds 1 for each level -- and concatenates each level of AssetID's to the SortPath column. SELECT recur.AssetID, recur.ParentID, recur.Asset, recur.Node, cte.HLevel + 1 AS HLevel, CAST(cte.SortPath + CAST(Recur.AssetID AS BINARY(4)) AS VARBINARY(8000)) AS SortPath FROM #tblAsset AS recur INNER JOIN cteBuildPath AS cte ON cte.AssetID = recur.ParentID)--==== This final INSERT/SELECT creates the "narrow surrogate" column (NodeNumber) SELECT AssetID, ParentID, Asset = SPACE((Hlevel-1)*4)+Asset, Node --,SortPath FROM cteBuildPath ORDER BY SortPath;
AssetID ParentID Asset Node-------------------- -------------------- ------------------------------ -----------3319 3214 Apartment 13320 3319 Building 1508 23323 3320 Room 210 33324 3320 Room 211 33321 3319 Building 1509 23322 3319 Building 1510 2