Я собираюсь бесстыдно украсть установку данных из другого ответа и продемонстрировать, как вы могли бы сделать это с hierarchyid` в:
create table t (code int, name varchar(100), under int)
insert into t values
(1, 'National Sales Manager', null),
(2, 'regional sales manager', 1),
(3, 'area sales manager', 2),
(4, 'sales manager', 3),
(5, 'a', null),
(6, 'b', 5),
(7, 'c', 5),
(8, 'd', 7),
(9, 'e', 7),
(10, 'f', 9),
(11, 'g', 9);
with cte as (
select code, name, under as parentCode, code as ultimateParent, cast('/' + cast(code as varchar) + '/' as nvarchar(max)) as h
from t
where under is null
union all
select child.code, child.name, child.under as ParentCode, parent.ultimateParentCode, cast(parent.h + cast(child.code as varchar) + '/' as nvarchar(max))
from t as child
join cte as parent
on child.under = parent.code
), hier as (
select code, name, parentCode, ultimateParentCode, cast(h as hierarchyid) as h
from cte
)
select code, name, parentCode, ultimateParentCode, h.ToString(), h.GetAncestor(h.GetLevel()-1).ToString()
from hier
Имейте в виду, рекурсивное CTE необходимо выполнить только один раз (или при изменении данных). То, что я делаю, заключается в том, что, как только вы вычислена иерархия (которую вы можете сохранить в строке, кстати), легко ответить на вопрос, который вы задаете, с вызовами метода на иерархии (и, возможно, соединение, если вы хотите чтобы вернуть информацию прародителя).
@MartinDavidValentinoSiagian: Я упомянул, что в вопросе, вторая структура таблицы. –