How to get recursivelevel using SQL Server 2012 hierarchyid?

空扰寡人 提交于 2019-12-11 07:14:22

问题


I know its quite challenging, Is there any sql specialist please kindly help me to solve this. I Have hierarchyID like below in NameHID column. Its representing /NameID/dadID/MomID/ respectively. Which means the students fatherid and the motherID. My Table Name is students.

this is my sample NAMEHID column

/2/8/5/

/5/11/12/

/8/7/9/

I need a output like

NameID   |  RecursiveLevel
2                 0
5                 1
7                 2
8                 1
9                 2
11                2
12                2

From this Pic you can see the what is the RecursiveLevel. This tree representing something like ancestors of a specific node.


I need to show only the NameID and the Recursive level as out put. if there Any other additional information need to do this?


回答1:


Your data is not correct hierachyid. You could do your job by using a split function and recursive cte

DECLARE @SampleData TABLE
(
   NAMEHID varchar(30)
)

INSERT INTO @SampleData
(
   NAMEHID
)
VALUES
('/2/8/5/'),('/5/11/12/'),('/8/7/9/')

;with temp AS
(
   SELECT * FROM @SampleData sd
   CROSS APPLY
   (
      SELECT * FROM [dbo].[SplitString](STUFF(LEFT(sd.NameHID,LEN(sd.NameHID) - 1),1,1,''),'/')
   ) cr
)
,cte AS
(
   SELECT t.NameHID, t.[Value] , 0 AS Lvl FROM temp t
   WHERE t.Pos = 1
   AND NOT EXISTS ( 
                SELECT * FROM temp t2 
                WHERE  t2.[Value] = t.[Value] AND t2.Pos > 1
               )  -- root ID
   UNION ALL 

   SELECT t2.NameHID, t2.[Value], cte.Lvl + 1 
   FROM  cte 
   INNER JOIN temp t ON cte.[Value] = t.[Value] AND t.Pos = 1
   INNER JOIN temp t2 ON t.NameHID = t2.NameHID AND t2.Pos > 1
)
SELECT cte.[Value] AS NameId, cte.Lvl 
FROM cte 
ORDER BY cte.Lvl, cte.[Value]
OPTION(MAXRECURSION 0)

Split function

CREATE FUNCTION [dbo].[SplitString] (@Text varchar(max),@Delimiter varchar(10))
Returns Table 
As
Return (  
   Select Pos = Row_Number() over (Order By (Select null))
        ,Value = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
   From (Select x = Cast('<x>'+ Replace(@Text,@Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A 
   Cross Apply x.nodes('x') AS B(i)
);

Demo link: http://rextester.com/KPX84657



来源:https://stackoverflow.com/questions/44016261/how-to-get-recursivelevel-using-sql-server-2012-hierarchyid

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