Dios mío, amigos ... usar un "CTE recursivo de conteo" o "rCTE" es tan malo o peor que usar un bucle. Consulte el siguiente artículo para saber por qué digo eso.
http://www.sqlservercentral.com/articles/T-SQL/74118/
Aquí hay una forma de hacerlo sin ningún RBAR, incluido el "RBAR oculto" de un rCTE de conteo.
--===== 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
;