В то время как сегменты последовательного вызова допускают обработку с помощью CTE, сегменты параллельного вызова создают довольно серьезный камень.
Следующий код назначит номера вызовов каждому вызову и соответствующим образом сгруппирует сегменты вызова:
-- Set up the test data.
declare @CallSegments as table ( CallSegmentId int )
insert into @CallSegments ( CallSegmentId ) values ( 1 ), ( 2 ), ( 3 ), ( 4 ), ( 5 ), ( 6 ), ( 7 ), ( 8 )
declare @CallSegmentLinks as table ( ParentCallSegmentId int, ChildCallSegmentId int )
insert into @CallSegmentLinks ( ParentCallSegmentId, ChildCallSegmentId ) values
( 1, 2 ), ( 2, 3 ), ( 3, 4 ),
( 6, 7 ), ( 6 , 8 )
-- Find all of the CallSegments which are not targets of CallSegmentLinks and assign a CallNumber to each.
declare @Calls as table ( InitialCallSegmentId bit, CallSegmentId int, CallNumber int )
insert into @Calls
select 1, CallSegmentId, Row_Number() over ( order by CallSegmentId ) as CallNumber
from @CallSegments
where not exists ( select 42 from @CallSegmentLinks where ChildCallSegmentId = CallSegmentId )
-- Add the remaining call segments.
insert into @Calls
select 0, CallSegmentId, NULL
from @CallSegments
where CallSegmentId not in ( select CallSegmentId from @Calls )
-- Propogate the CallNumber to the remaining call segments.
while ( @@RowCount > 0 )
begin
update Child
set CallNumber = Parent.CallNumber
from @Calls as Parent inner join
@CallSegmentLinks as CSL on CSL.ParentCallSegmentId = Parent.CallSegmentId inner join
@Calls as Child on Child.CallSegmentId = CSL.ChildCallSegmentId
where Child.CallNumber is NULL and Parent.CallNumber is not NULL
end
-- Display the grouped call segments with the initial call segment for each call shown first.
select * from @Calls order by CallNumber, InitialCallSegmentId desc, CallSegmentId
Обратите внимание, что первый сегмент вызова в каждом вызове помечен.Это может помочь вам написать дополнительный код, который отслеживает сегменты в вызове в заказе или по вашему собственному замыслу.