O rany... używanie "zliczania rekurencyjnego CTE" lub "rCTE" jest tak samo złe lub gorsze niż użycie pętli. Przeczytaj poniższy artykuł, aby dowiedzieć się, dlaczego to mówię.
http://www.sqlservercentral.com/articles/T-SQL/74118/
Oto jeden ze sposobów na zrobienie tego bez żadnego RBAR, w tym „ukrytego RBAR” zliczającego rCTE.
--===== Declare and preset some obviously named variables
DECLARE @StartDate DATETIME,
@EndDate DATETIME
;
SELECT @StartDate = '2010-01-14', --We'll get the month for both of these
@EndDate = '2020-12-05' --dates and everything in between
;
WITH
cteDates AS
(--==== Creates a "Tally Table" structure for months to add to start date
-- calulated by the difference in months between the start and end date.
-- Then adds those numbers to the start of the month of the start date.
SELECT TOP (DATEDIFF(mm,@StartDate,@EndDate) + 1)
MonthDate = DATEADD(mm,DATEDIFF(mm,0,@StartDate)
+ (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1),0)
FROM sys.all_columns ac1
CROSS JOIN sys.all_columns ac2
)
--===== Slice each "whole month" date into the desired display values.
SELECT [Year] = YEAR(MonthDate),
[Month] = MONTH(MonthDate)
FROM cteDates
;