CREATE TABLE #t
(
id int NOT NULL PRIMARY KEY
,tree varchar(50) NOT NULL
);
INSERT INTO #t
VALUES (1, '1')
,(2, '1.1')
,(3, '1.1.1')
,(4, '1.2')
,(5, '1.2.1')
,(6, '1.2.2')
,(7, '1.2.2.1')
,(8, '1.2.2.2')
,(9, '1.3')
,(10, '1.3.1')
,(11, '1.3.2')
,(12, '1.3.3')
,(13, '1.3.3.1')
,(14, '1.3.3.2');
Try:
WITH pTrees
AS
(
SELECT T.id, T.tree
,REVERSE(SUBSTRING(X.rTree, CHARINDEX('.', X.rTree) + 1, 50)) AS pTree
FROM #t T
CROSS APPLY
(
VALUES(REVERSE(T.tree))
) X (rTree)
)
SELECT T.id
,CASE
WHEN T.id = P.id
THEN 0
ELSE P.id
END AS pid
,T.tree
FROM pTrees T
JOIN #t P
ON T.pTree = P.tree;
If you are going to use hierarchyid you need to use GetAncestor:
WITH Hierarchy
AS
(
SELECT T.id, T.tree, X.hid
,X.hid.GetAncestor(1) AS phid
FROM #t T
CROSS APPLY
(
VALUES(CAST('/' + REPLACE(T.tree,'.','/') + '/' AS hierarchyid))
) X (hid)
)
SELECT H.id, COALESCE(P.id, 0) AS pid, H.tree
FROM Hierarchy H
LEFT JOIN Hierarchy P
ON H.phid = P.hid;