Предполагая, что я правильно интерпретирую данные, вот что у меня есть:
-- first, establish the hierarchy and while doing that
-- add a hierarchyid column
with d as (select * from (
values
(1, 'A', Null, 0),
(2, 'B', 'A', 1),
(3, 'C', 'B', 1),
(4, 'D', 'C', 0),
(5, 'E', 'B', 0)
) as x(ID, Employee, Manager, IsPartTime)
)
, r as (
select ID, Employee, Manager, IsPartTime, cast(concat('/', d.ID, '/') as varchar(max)) as h
from d
where Manager is null
union all
select child.ID, child.Employee, child.Manager, child.IsPartTime, cast(concat(parent.h, child.ID, '/') as varchar(max)) as h
from r as parent
join d as child
on child.Manager = parent.Employee
)
select ID, Employee, Manager, IsPartTime, cast(h as hierarchyid) as h
into #t
from r;
После того, как сложная часть сделана, мы можем посмотреть, кто нуждается в обновлении, используя иерархию икоррелированный подзапрос.
with u as (
select *, (
select top(1) Employee
from #t as a
-- this person is a subordinate of the person from the main table
where t.h.IsDescendantOf(a.h) = 1
-- exclude the employee themselves from consideration
and t.ID <> a.ID
-- the manager needs to be full-time.
and a.IsPartTime = 0
order by a.h.GetLevel()
) as NewManager
from #t as t
where IsPartTime = 0
)
select *
from u
where Manager <> NewManager;