Du løber ind i en uendelig løkke forårsaget af cyklusser i dine data, f.eks.:1> 2> 3> 2> ... . Løsningen er at holde styr på de rækker, der allerede er "forbrugt". På grund af begrænsninger i CTE'er skal dette gøres ved at inkludere historikken inden for hver CTE-række, f.eks. ved at samle stien fulgt for at nå frem til hver række. Du kan fjerne kommentarer til , Path
ved det sidste select
for at se, hvad der foregår.
-- Sample data.
declare @ACC as Table ( AccNo Int, Property Char );
insert into @ACC values
( 1, 'A' ), ( 1, 'B' ), ( 2, 'A' ), ( 2, 'C' ), ( 3, 'C' ), ( 4, 'D' );
select * from @ACC;
-- Recursive CTE.
with Groups as (
select distinct AccNo, AccNo as LinkedAccNo,
Cast( '|' + Cast( AccNo as VarChar(10) ) + '|' as VarChar(1024) ) as Path
from @ACC
union all
select G.AccNo, A.AccNo, Cast( Path + Cast( A.AccNo as VarChar(10) ) + '|' as VarChar(1024) )
from Groups as G inner join -- Take the latest round of new rows ...
@ACC as AP on AP.AccNo = G.LinkedAccNo inner join -- ... and get the Property for each ...
@ACC as A on A.Property = AP.Property -- ... to find new linked rows.
where G.Path not like '%|' + Cast( A.AccNo as VarChar(10) ) + '|%' )
select AccNo, LinkedAccNo -- , Path
from Groups
order by AccNo, LinkedAccNo;