On SQL Server 2005 at least, this works efficiently where we have an indexed row number.It does seem to be very sensitive to the join condition in the recursive part of the CTE: changing it to the equivalent "ON T.rn - 1 = RT.rn" results in a scan of T each time instead of a seek!DROP TABLE dbo.T-- rn must have contiguous values for this to work:CREATE TABLE dbo.T (rn int PRIMARY KEY, f float NOT NULL)-- 100000 random floats between 0 and 1:INSERT INTO dbo.TSELECT n+1 AS rn, RAND(CAST(NEWID() AS binary(4))) AS fFROM dbo.NumbersGO;WITH RT AS ( SELECT rn, f AS rt FROM dbo.T WHERE rn = 1 UNION ALL SELECT T.rn, RT.rt + T.f FROM RT INNER JOIN dbo.T AS T ON T.rn = RT.rn + 1)SELECT *INTO dbo.TRTFROM RT--ORDER BY rnOPTION (MAXRECURSION 0)
SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 1 ms.Table 'Worktable'. Scan count 2, logical reads 600001, physical reads 0,read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.Table 'T'. Scan count 100000, logical reads 200002, physical reads 0,read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.SQL Server Execution Times: CPU time = 3500 ms, elapsed time = 3724 ms.(100000 row(s) affected)