Следующий код демонстрирует один способ обхода иерархии с использованием рекурсивного CTE.Поменяв окончательный оператор select
на альтернативные, вы можете отобразить промежуточные результаты, чтобы получить некоторое представление о том, как он работает.
-- Sample data.
declare @Samples as Table ( IdCtgArt Int, DescCtg VarChar(32), IdNodo Int );
insert into @Samples ( IdCtgArt, DescCtg, IdNodo ) values
( 1, 'GRANDI ELETTRODOMENSTICI', 0 ),
( 3, 'PICCOLI ELETTRODOMESTICI', 0 ),
( 15, 'INCASSO', 0 ),
( 7, 'CONSERVAZIONE', 1 ),
( 35, 'Lavaggio e asciugatura', 1 ),
( 18, 'Frigoriferi', 7 ),
( 44, 'Frigoriferi', 7 ),
( 32, 'DOPPIA PORTA', 18 ),
( 82, 'MONO PORTA', 44 );
select * from @Samples;
-- Build the tree.
with
LeafNodes as (
-- Get the leaf nodes, i.e. those with no children.
select IdCtgArt, DescCtg, IdNodo
from @Samples as SP
where not exists ( select 42 from @Samples as SC where SC.IdNodo = SP.IdCtgArt ) ),
Tree as (
-- Start at the leaf nodes ...
select IdCtgArt, DescCtg, IdNodo, IdCtgArt as LeafId, 0 as Depth, Cast( DescCtg as VarChar(1024) ) as Path
from LeafNodes as LN
union all
-- ... and work up one level at a time adding parents.
select S.IdCtgArt, S.DescCtg, S.IdNodo, T.LeafId, T.Depth + 1, Cast( S.DescCtg + ', ' + T.Path as VarChar(1024) )
from Tree as T inner join
@Samples as S on S.IdCtgArt = T.IdNodo
),
InterestingRows as (
-- Interesting rows are those that start from the leaf nodes and have the maximum depth.
select LeafId, Max( Depth ) as MaxDepth
from Tree as T
where T.LeafId in ( select IdCtgArt from LeafNodes )
group by LeafId )
-- The result is interesting rows which have a depth greater than zero, i.e. leaf nodes with at least one level of parent.
select T.IdCtgArt, T.Path
from Tree as T inner join
InterestingRows as IR on IR.LeafId = T.LeafId and IR.MaxDepth = T.Depth
where T.Depth > 0;
-- Replace the final select with one of these statements to see the intermediate results:
-- select * from LeafNodes;
-- select * from Tree;
-- select * from InterestingRows;
В результате получается одна дополнительная строка вывода: 1, 'GRANDI ELETTRODOMENSTICI, Lavaggio e asciugatura'
.Неясно, почему ваши данные выборки исключают эту строку.