If I understand correctly you just want to terminated the recursion once it has come back to where it started from.
One option would be to add a column like StartPoint
or whatever you want to call it and then use that in the where clause to terminate the recursion or filter those out.
Without knowing specifically what your desired output is, I made the assumption this was what you were after based on the sample data, comments added in code:
DECLARE @TestData TABLE
(
[From] INT
, [To] INT
, [Total] INT
, [type] CHAR(1)
);
INSERT INTO @TestData (
[From]
, [To]
, [Total]
, [type]
)
VALUES ( 98579, 10406, 82, 'B' ) , ( 98579, 17005, 5834, 'S' ) , ( 98579, 18879, 6323, 'S' ) , ( 98579, 18889, 215, 'S' ) , ( 10406, 43594, 234, 'B' ) , ( 10406, 73959, 10, 'B' ) , ( 10406, 98579, 22824, 'B' ) , ( 43594, 83827, 4, 'S' ) , ( 43594, 38475, 543, 'S' );
WITH [x]
AS (
-- anchor:
SELECT [b].[From] AS [StartPoint] --Where are we starting
, [b].[From]
, [b].[To]
, [b].[Total]
, [b].[type]
, 0 AS [levels]
FROM @TestData [b]
WHERE [b].[From] = 98579
UNION ALL
-- recursive:
SELECT [x].[StartPoint] --Add it here
, [tm].[From]
, [tm].[To]
, [tm].[Total]
, [tm].[type]
, [x].[levels] + 1
FROM @TestData AS [tm]
INNER JOIN [x]
ON [x].[To] = [tm].[From]
WHERE [x].[StartPoint] <> [tm].[From] --stop the recursion once we have come back to where it started, filter those out.
)
SELECT [x].[From]
, [x].[To]
, [x].[Total]
, [x].[type]
, [x].[levels]
FROM [x]
ORDER BY [x].[levels];
Giving results:
From To Total type levels
----------- ----------- ----------- ---- -----------
98579 10406 82 B 0
98579 17005 5834 S 0
98579 18879 6323 S 0
98579 18889 215 S 0
10406 43594 234 B 1
10406 73959 10 B 1
10406 98579 22824 B 1
43594 83827 4 S 2
43594 38475 543 S 2
In this example I included where you added the filter WHERE [b].[From] = 98579
which wasn't clear if that was to show the example of the circular reference or you are doing that to indicated your starting point.
If you remove that where clause in the above code it will give all of it. Basically each row is consider the StartPoint
and you will get all recurrences for each of those rows, but will stop/filter out once it has come back to where it started:
Giving you:
From To Total type levels
----------- ----------- ----------- ---- -----------
98579 10406 82 B 0
98579 17005 5834 S 0
98579 18879 6323 S 0
98579 18889 215 S 0
10406 43594 234 B 0
10406 73959 10 B 0
10406 98579 22824 B 0
43594 83827 4 S 0
43594 38475 543 S 0
98579 10406 82 B 1
98579 17005 5834 S 1
98579 18879 6323 S 1
98579 18889 215 S 1
43594 83827 4 S 1
43594 38475 543 S 1
10406 43594 234 B 1
10406 73959 10 B 1
10406 98579 22824 B 1
43594 83827 4 S 2
43594 38475 543 S 2