SQL返回特定年份以来的年份列表

时间:2009-03-09 15:49:23

标签: sql-server sql-server-2005 tsql

我需要一个年份列表作为记录集,从2004年到当年(以desc顺序),而不编写存储过程。这可能吗? (SQL Server 2005)。所以它应该返回:

2009
2008
2007年
2006年
2005年
2004年

10 个答案:

答案 0 :(得分:46)

这使用递归CTE从2004年到现在的所有年份:

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;

答案 1 :(得分:4)

在任何足够大(稳定)的表中的任何列上使用ROW_NUMBER都是一种方法。

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

请注意,<AnyTable>应至少包含等于您需要的年数的行数。

编辑(Cudo's to Joshua)

  • 最好选择一个您知道不会被截断和/或删除的表格。应该想到足够大的system table
  • 目前,年龄更大,更聪明(至少年龄更大),我会使用约书亚给出的答案中提到的CTE来实现这一要求。与当前给定的CTE解决方案相比,ROW_NUMBER技术更优越且更不容易出错。

答案 2 :(得分:4)

更新以返回当前年份加上前5年。应该非常快,因为这是一个小记录集。

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

答案 3 :(得分:3)

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

答案 4 :(得分:1)

试试这个:

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

返回

2009
2008
2007
2006
2005
2004

当您点击2010年1月1日时。相同的代码将返回:

2010
2009
2008
2007
2006
2005
2004

答案 5 :(得分:1)

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

答案 6 :(得分:0)

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

答案 7 :(得分:0)

这是一个简单的查询,请查看

(SELECT REPLACE((TO_CHAR(SYSDATE,'YYYY')-Rownum)+1,' ',NULL) yr FROM dual CONNECT BY LEVEL < 32) year

答案 8 :(得分:0)

我的两分钱

CTE是最好的答案,但我喜欢@Lieven Keersmaekers的答案,因为它不依赖于递归/循环或创建其他对象(如函数/日期表)。关键的变化是,我只是简单地使用带有表达式的Top子句,而不是前100个(基本上是整个表格),我首先要求N个无序行。如果您的基表恰好很大,这会更快。

在SQL Server 2016上测试

DECLARE @startYear smallint;
SET @startYear = 2004;

DECLARE @endYear smallint;
SET @endYear = YEAR(GETDATE());

-- Top uses expression to bring in N number of rows. The (@startYear - 1) is to retain the start year
SELECT [Yr]
FROM (
    SELECT TOP (@endYear - (@startYear - 1)) 
          COUNT([object_id]) OVER (ORDER BY [object_id] DESC) + (@startYear - 1) AS [Yr] -- Add initial start year to Count
    FROM sys.all_objects
) AS T1
ORDER BY [Yr] DESC

上面的注释是有效的,但是由于OP的要求实际上是2004年以来的一小部分值,因此sys.all_objects就足够了,因为SQL Server安装附带了大量的系统对象。

希望这是另一回事。

答案 9 :(得分:-1)

我认为你需要创建一个日期表,然后从中选择你的范围。当您需要选择附加了X数据的日期范围且没有任何错过的日期时,它也会非常有用。