SQL to return list of years since a specific year

Updated to return current year plus previous 5 years. Should be very fast as this is a small recordset.

SELECT YEAR(GETDATE()) as YearNum
UNION
SELECT YEAR(GETDATE()) - 1 as YearNum
UNION
SELECT YEAR(GETDATE()) - 2 as YearNum
UNION
SELECT YEAR(GETDATE()) - 3 as YearNum
UNION
SELECT YEAR(GETDATE()) - 4 as YearNum
UNION
SELECT YEAR(GETDATE()) - 5 as YearNum
ORDER BY YearNum DESC

DECLARE @YEARS TABLE (Y INT)
DECLARE @I INT, @NY INT
SELECT @I = 2004, @NY = YEAR(GETDATE())
WHILE @I <= @NY BEGIN
    INSERT @YEARS SELECT @I
    SET @I = @I + 1
END
SELECT Y 
FROM @YEARS
ORDER BY Y DESC

This gets all years from 2004 to the present, using a recursive CTE:

with yearlist as 
(
    select 2004 as year
    union all
    select yl.year + 1 as year
    from yearlist yl
    where yl.year + 1 <= YEAR(GetDate())
)

select year from yearlist order by year desc;

Using ROW_NUMBER on any column from any large enough (stable) table would be one way to do it.

SELECT *
FROM (
  SELECT TOP 100 2003 + ROW_NUMBER() OVER (ORDER BY <AnyColumn>) AS Yr
  FROM dbo.<AnyTable>
  ) Years
WHERE Yr <= YEAR(GETDATE())

Note that <AnyTable> should contain at least the amount of rows equal to the amount of years you require.

Edit (Cudo's to Joshua)

  • Preferably, you'd select a table wich you know will not get truncated and/or deleted. A large enough system table should come to mind.
  • At present, being a lot older and wiser (older at least), I would implement this requirement using a CTE like mentioned in the answer given by Joshua. The CTE technique is far superior and less error prone than current given ROW_NUMBER solution.