Reputation: 95
I need a month list for three years , but I get three different result sets instead of one list (so with 36 lines). I'm quite new to SQL server so I could be completely wrong in the logic here below ;).
declare @yearlist table (value int)
declare @year int
INSERT INTO @yearlist VALUES (year(getdate())-1)
INSERT INTO @yearlist VALUES (year(getdate())+0)
INSERT INTO @yearlist VALUES (year(getdate())+1)
DECLARE db_cursor CURSOR FOR
SELECT Value FROM @yearlist
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @year
WHILE @@FETCH_STATUS = 0
BEGIN
;with mths as(
select 1 as mth, DATENAME(MONTH, cast(@year*100+1 as varchar) + '01') as monthname, RIGHT(CAST(@year AS CHAR(4)),2) AS yr2, @year as yr
union all
select mth+1, DATENAME(MONTH, cast(@year*100+(mth+1) as varchar) + '01'), RIGHT(CAST(@year AS CHAR(4)),2) AS yr2, @year as yr
from mths where mth<12
)
select yr2 + RIGHT('00' + CONVERT(NVARCHAR(2), mth), 2) as monthID,
* from mths
FETCH NEXT FROM db_cursor INTO @year
END
CLOSE db_cursor
DEALLOCATE db_cursor
But this is the needed data:
1701 January 2017
1702 February 2017
1703 March 2017
1704 April 2017
1705 May 2017
etc...
1908 August 2019
1909 September 2019
1910 October 2019
1911 November 2019
1912 December 2019
Where the year must be the past, current and next year (dynamic).
Upvotes: 0
Views: 90
Reputation: 246
If you are only interested on past, current and next year, following query should work for you
SELECT RIGHT(YEAR(GETDATE())-1, 2) + right ('00'+ltrim(str(mth )),2 ) , DateName( month , DateAdd( month , mth , 0 ) - 1 ), YEAR(GETDATE())-1 FROM (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) AS X(mth)
UNION ALL
SELECT RIGHT(YEAR(GETDATE()), 2) + right ('00'+ltrim(str(mth )),2 ), DateName( month , DateAdd( month , mth , 0 ) - 1 ), YEAR(GETDATE()) FROM (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) AS X(mth)
UNION ALL
SELECT RIGHT(YEAR(GETDATE())+1, 2) + right ('00'+ltrim(str(mth )),2 ), DateName( month , DateAdd( month , mth , 0 ) - 1 ), YEAR(GETDATE()) + 1 FROM (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) AS X(mth)
Upvotes: 0
Reputation: 95554
Ideally, you if this is going to be a repeating thing, where the values could change, you may well want a Calendar Table.
Otherwise, you could use an inline tally table:
DECLARE @StartYear int = 2017,
@EndYear int = 2019;
DECLARE @StartDate date = CONVERT(varchar(4),@StartYear) + '0101',
@EndDate date = DATEADD(YEAR,1,CONVERT(varchar(4),@EndYear) + '0101');
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM N N1 --10
CROSS JOIN N N2 --100
CROSS JOIN N N3 --1000
)
SELECT RIGHT(DATEPART(YEAR, V.D),2) + RIGHT('0' + CONVERT(varchar(2),DATEPART(MONTH,V.D)),2) AS YearMonth,
DATENAME(MONTH, V.D) AS [MonthName],
DATEPART(YEAR, V.D) AS [Year]
FROM Tally T
CROSS APPLY (VALUES(DATEADD(MONTH, T.I, @StartDate))) V(D)
WHERE V.D < @EndDate;
This solution covers you for up to 1000 months (just over 83 years), so should be more than enough.
Upvotes: 3