Везде куда не глянь, есть иерархии, в армии, на работе, в жизни и быту,
так уж устроен мир одни управляют другими……
Допустим нужно вывести иерархический справочник в виде списка чтобы визуально было понятно кто кому зачем и почему)
для этого нужна простая иерархия родитель-потомок, построим на примере сотрудников, здесь ID потомок, MgrID родитель.
Самыми главными будем считать тех у кого нет босов т. е WHERE MgrID IS NULL
WITH Employee (ID, Name, MgrID) AS
(
SELECT 1, 'Keith', NULL UNION ALL
SELECT 2, 'Josh', 1 UNION ALL
SELECT 3, 'Robin', 1 UNION ALL
SELECT 4, 'Raja', 2 UNION ALL
SELECT 5, 'Tridip', NULL UNION ALL
SELECT 6, 'Arijit', 5 UNION ALL
SELECT 7, 'Amit', 5 UNION ALL
SELECT 8, 'Dev', 6
)
--------------------------------------------
-- Recursive CTE - Chained to the above CTE
--------------------------------------------
,Hierarchy AS
(
-- Anchor
SELECT ID
,Name
,MgrID
,nLevel = 1
,Family = ROW_NUMBER() OVER (ORDER BY Name)
,CAST(Name as VARCHAR(255)) as orderSequence
FROM Employee
WHERE MgrID IS NULL
UNION ALL
-- Recursive query
SELECT E.ID
,E.Name
,E.MgrID
,H.nLevel+1
,Family
,CAST(H.orderSequence + '\' + E.Name as VARCHAR(255))
FROM Employee E
JOIN Hierarchy H ON E.MgrID = H.ID
)
SELECT H.*,replicate(' ',nLevel*5)+Name as Hname
FROM Hierarchy H
ORDER BY orderSequence
Вот вам и готовый результат
В дополнение как избежать циклов в графах при поиске путей
drop table if exists #hier
create table #hier
(
id int identity(1,1),
parent int null,
child int null
)
insert into #hier
select null,1
union
select 1,2
union
select 1,3
union
select 2,4
union
select 3,5
union
select 2,6
union
select 4,1
;with hierarchy
as
(
select
child, parent, 0 as cycle,
CAST('.' as varchar(max)) + LTRIM(child) + '.' as [path]
from #hier
where parent is null
union all
select
c.child,c.parent,case when p.[path] like '%.' + LTRIM(c.child) + '.%' then 1 else 0 end as cycle,
p.[path] + LTRIM(c.child) + '.' as [path]
from
hierarchy as p
inner join #hier as c on p.child = c.parent
and p.cycle = 0
)
select
child,parent,[path],cycle from
hierarchy h
--where h.path like '%.1104.%.1031.%'
И наконец немного юмора
Девушка на свидании спрашивает у парня: — Вась, а ты до меня за кем-нибудь ухаживал? — Да, в деревне за скотиной...