Reputation: 5831
I have a Dimension table that I will need to display the YYYYMM for over the next 50 years. I am sure that there is a way to do this without manually entering the data, but I am not sure the appropriate way to do so.
My table has
An ID which is an int that will display YYYYMM
the month that will be a varchar(2) to display MM
and the year that will be a varchar(4) to display YYYY
Would anyone be able to help me out with this? I have never really had to write a script before and the examples I have seen online are more showing with datetime data types.
I would also probably like to start a few years back for already existing data. Let's say 2010 - 2070
Upvotes: 0
Views: 2100
Reputation: 93744
I will do this using tally table with stacked cte
. Try this
declare @start_year varchar(4)='2010',@end_year varchar(4)='2070'
;WITH e1(n) AS
(
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), -- 10
e2(n) AS (SELECT 1 FROM e1 CROSS JOIN e1 AS b), -- 10*10
e3(n) AS (SELECT 1 FROM e2 CROSS JOIN e2 AS b), -- 100*100
e4(n) AS (SELECT 1 FROM e3 CROSS JOIN (SELECT TOP 5 n FROM e1) AS b) -- 5*10000
,e5 as (SELECT Dateadd(Month, Row_number()OVER (
ORDER BY n) - 1, Cast(@start_year + '-01-01' AS DATE)) AS dates
FROM e4)
SELECT Id=LEFT(CONVERT(CHAR(8), dates, 112), 6),
[Month]=Month(dates),
[Year]=Year(dates)
FROM e5
WHERE Year(dates) <= @end_year
Upvotes: 0
Reputation: 35790
This works for me
DECLARE @t TABLE
(
id INT ,
m VARCHAR(2) ,
y VARCHAR(4)
)
DECLARE @i INT = 1
DECLARE @today DATE = '20150121'
DECLARE @endDate DATE = DATEADD(YEAR, 50, @today)
WHILE @today <= @endDate
BEGIN
INSERT INTO @t
( id ,
m ,
y
)
VALUES ( CAST(LEFT(CONVERT(CHAR(8), @today, 112), 6) AS INT) ,
SUBSTRING(CONVERT(CHAR(8), @today, 112), 5, 2) ,
LEFT(CONVERT(CHAR(8), @today, 112), 4)
)
SET @today = DATEADD(MONTH, 1, @today)
END
Output:
id m y
201501 01 2015
201502 02 2015
201503 03 2015
201504 04 2015
201505 05 2015
201506 06 2015
201507 07 2015
201508 08 2015
201509 09 2015
201510 10 2015
201511 11 2015
201512 12 2015
201601 01 2016
201602 02 2016
201603 03 2016
. . .
206410 10 2064
206411 11 2064
206412 12 2064
206501 01 2065
Upvotes: 1