SQL para devolver la lista de años desde un año específico


Necesito una lista de años como un conjunto de registros desde 2004 hasta el año actual (en orden desc), sin escribir un procedimiento almacenado. Es esto posible? (SQL Server 2005). Así que debe volver:

2009
2008
2007
2006
2005
2004

Author: brian, 2009-03-09

9 answers

Esto obtiene todos los años desde 2004 hasta el presente, usando un CTE recursivo:

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;
 41
Author: Joshua Carmody,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-15 14:24:14

Actualizado para devolver el año en curso más los 5 años anteriores. Debería ser muy rápido ya que este es un pequeño conjunto de registros.

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
 4
Author: DJ.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-09 16:19:29

Usar ROW_NUMBER en cualquier columna de cualquier tabla lo suficientemente grande (estable) sería una forma de hacerlo.

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

Tenga en cuenta que <AnyTable> debe contener al menos la cantidad de filas igual a la cantidad de años que necesita.

Editar (Cudo a Josué)

  • Preferiblemente, debe seleccionar una tabla que sepa que no se truncará y/o eliminará. Un system table suficientemente grande debería venir a la mente.
  • En la actualidad, siendo mucho más viejo y sabio (al menos mayor), me gustaría implementar este requisito utilizando un CTE como se menciona en la respuesta dada por Josué. La técnica CTE es muy superior y menos propensa a errores que la actual solución dada ROW_NUMBER.
 4
Author: Lieven Keersmaekers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-01 06:43:25
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
 3
Author: Maksym Gontar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-09 16:03:40

Prueba esto:

    declare @lowyear int
set @lowyear = 2004
declare @thisyear int
set @thisyear = year(getdate())
while @thisyear >= @lowyear
begin
print @thisyear
set @thisyear = (@thisyear - 1)
end

Devuelve

2009
2008
2007
2006
2005
2004

Cuando llegue el 1 de enero de 2010. El mismo código regresará:

2010
2009
2008
2007
2006
2005
2004
 1
Author: Eppz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-09 18:04:54
WITH n(n) AS
(
    SELECT 0
    UNION ALL
    SELECT n+1 FROM n WHERE n < 10
)
SELECT year(DATEADD( YY, -n, GetDate())) 
FROM n ORDER BY n
 1
Author: sunny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-07 05:39:08
SET NOCOUNT ON
DECLARE @max int
set @max = DATEPART(year, getdate())

CREATE TABLE #temp (val int)

while @max >= 2004
  BEGIN
    insert #temp(val) values(@max)
    set @max = @max - 1
  END

SELECT * from #temp
 0
Author: scottm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-09 16:05:45

Esta es una consulta simple, marque esta

(SELECT REPLACE((TO_CHAR(SYSDATE,'YYYY')-Rownum)+1,' ',NULL) yr FROM dual CONNECT BY LEVEL < 32) year
 0
Author: user3852207,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-18 08:51:03

Creo que necesita crear una tabla de fechas, luego simplemente seleccione su rango de ella. También puede ser útil cuando necesita seleccionar un rango de fechas con X datos adjuntos y no tener días perdidos.

 -1
Author: Andrew Clark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-09 15:58:34