• All you have to set / pass in is the "@number_of_months", although you could pass in a different ending month if you wanted to.


    DECLARE @number_of_months int
    SET @number_of_months = 24

    --------------------------------------------------------------------------------

    DECLARE @start_month date
    DECLARE @end_month date

    --SET @end_month = '20171113'
    SET @end_month = ISNULL(@end_month, GETDATE())
    SET @start_month = DATEADD(MONTH, DATEDIFF(MONTH, 0, @end_month) - @number_of_months + 1, 0)

    ;WITH
    cteTally10 AS (
      SELECT * FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) AS numbers(number)
    ),
    cteTally100 AS (
      SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS number
      FROM cteTally10 c1
      CROSS JOIN cteTally10 c2
    )
    SELECT YEAR(first_day_of_month) AS year, CAST(DATENAME(MONTH, first_day_of_month) AS char(3)) AS mon,
      first_day_of_month, DATEADD(DAY, -1, DATEADD(MONTH, 1, first_day_of_month)) AS last_day_of_month
    FROM cteTally100 months
    CROSS APPLY (
      SELECT DATEADD(MONTH, months.number - 1, @start_month) AS first_day_of_month
    ) AS ca1
    WHERE months.number <= @number_of_months

    SQL DBA,SQL Server MVP(07, 08, 09) "It's a dog-eat-dog world, and I'm wearing Milk-Bone underwear." "Norm", on "Cheers". Also from "Cheers", from "Carla": "You need to know 3 things about Tortelli men: Tortelli men draw women like flies; Tortelli men treat women like flies; Tortelli men's brains are in their flies".