SQL возвращает список лет с определенного года - PullRequest
27 голосов
/ 09 марта 2009

Мне нужен список лет в виде набора записей, начиная с 2004 по текущий год (в порядке убывания), без написания хранимой процедуры . Это возможно? (SQL Server 2005). Так и должно вернуться:

2009
2008
2007
2006
2005
2004

Ответы [ 9 ]

46 голосов
/ 15 апреля 2011

Получается все годы с 2004 года по настоящее время с использованием рекурсивного 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;
4 голосов
/ 09 марта 2009

Обновлено, чтобы вернуть текущий год плюс предыдущие 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
4 голосов
/ 09 марта 2009

Использование 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> должно содержать как минимум количество строк, равное количеству лет, которое вам требуется.

Edit (Cudo's to Joshua)

  • Желательно, чтобы вы выбрали таблицу, которая, как вы знаете, не будет усечена и / или удалена. Достаточно большой system table должен прийти в голову.
  • В настоящее время, будучи намного старше и мудрее (по крайней мере, старше), я бы выполнил это требование, используя CTE, как упомянуто в ответе Джошуа. Техника CTE намного лучше и менее подвержена ошибкам, чем текущее решение ROW_NUMBER.
3 голосов
/ 09 марта 2009
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
1 голос
/ 07 ноября 2014
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 голос
/ 09 марта 2009

Попробуйте это:

    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

Когда вы нажмете 1 января 2010. Тот же код вернется:

2010
2009
2008
2007
2006
2005
2004
0 голосов
/ 18 июля 2014

Это простой запрос, отметьте это

(SELECT REPLACE((TO_CHAR(SYSDATE,'YYYY')-Rownum)+1,' ',NULL) yr FROM dual CONNECT BY LEVEL < 32) year
0 голосов
/ 09 марта 2009
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 голосов
/ 09 марта 2009

Я думаю, вам нужно создать таблицу дат, а затем просто выбрать из нее диапазон. Это также может пригодиться, когда вам нужно выбрать диапазон дат с прикрепленными данными X и без пропущенных дней.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...