Najpowszechniej stosowanym podejście byłoby rekurencyjnego Expression tabelowym (CTE)
WITH Ancestors(Id, [Name], AncestorId) AS
(
SELECT
Id, [Name], Id.GetAncestor(1)
FROM
dbo.HierarchyTable
WHERE
Name = 'Joe Blow' -- or whatever you need to select that node
UNION ALL
SELECT
ht.Id, ht.[Name], ht.Id.GetAncestor(1)
FROM
dbo.HierarchyTable ht
INNER JOIN
Ancestors a ON ht.Id = a.AncestorId
)
SELECT *, Id.ToString() FROM Ancestors
(adaptacja Simon Ince blog post)
Simon Ince również Proponuje drugie podejście, gdzie właśnie zasadzie odwraca stan - zamiast wykrywać te dane osobowe, które są przodek osoby docelowej, odwraca zaznaczenie wokół:
DECLARE @person hierarchyid
SELECT @person = Id
FROM dbo.HierachyTable
WHERE [Name] = 'Joe Blow';
SELECT
Id, Id.ToString() AS [Path],
Id.GetLevel() AS [Level],
Id.GetAncestor(1),
Name
FROM
dbo.HierarchyTable
WHERE
@person.IsDescendantOf(Id) = 1
Pozwoli to wybrać wszystkie wiersze z tabeli, gdzie docelową osobą, którą jesteś zainteresowany, jest potomek - dowolnego poziomu w hierarchii. Dzięki temu bezpośrednie i nieodległe przodki danej osoby docelowej znajdą się aż do rdzenia.
nie jest 'child.IsDescendantOf (rodzic)' taka sama jak 'parent.IsAncestorOf (dziecko)'? – Gabe