Populating Date Dimension with Fiscal Periods
A standard method for populating a date table with fiscal periods will always come to grief over exceptions. This post includes a procedure that should be customisable enough to cater for most variations on fiscal periods – provided all periods contain a whole number of weeks.
Fiscal Periods
… do vary.
- A 4-4-5 week pattern is standard… except when adjustments are made for busy months.
- Normally a quarter contains three months… except when a company is adjusting its financial year end.
The procedure detailed below takes a few parameters which specify the fiscal period schema:
- FirstDayOfFiscalYear : the day it all starts, which also determines the first-day-of-week.
- WeeksPerMonthPattern : a csv list stating the number of weeks in each month. e.g. 4,4,5,4,4,5,4,4,5,4,5,4. The procedure defaults to 4-4-5 throughout the year.
- MonthsPerQuarterPattern : a csv list stating the number of months per quarter. defaults to 3,3,3,3 so only needs overriding in those exceptional circumstances.
There is some validation to ensure that the numbers of months, quarters and weeks align. There’s a “checksum” NbrOfWeeks parameter which defaults to 52; set a value if 53 weeks applies – or for fiscal years with other numbers of weeks.
Columns to Update
A date table might have any number of specialised fiscal columns to update – week and month numbers, start and end date keys, overall period counts. Therefore the procedure provides a simple but flexible way of specifying an update clause using placeholders for values to be inserted.
- TableToUpdate : name of table
- DateKeyColumn : The Date-key column of the TableToUpdate. Column must be integer conversion of date format 112 (yyyymmdd).
- ColumnUpdatePattern : The contents of a SET clause as it would appear in a an UPDATE statement, with placeholders. E.g. “FiscalMonthNumber={m}, FiscalQuarterNumber={q},… FiscalMonthStart={mst},…”. Available placeholders:
- {year} : the value of @FiscalYearName
- {d}, {w}, {m}, {q}, {s} : day, week, month, quarter and semester numbers.
- {wst}, {mst}, {qst}, {sst} : week, month, quarter, semester start date key
- {wend}, {mend}, {qend}, {send} : week, month, quarter, semester end date key
Procedure ai_GenerateFiscalCalendar
This procedure generates table update statements for a single financial year.
Fiscal Calendar Update Generator.sql
Example Call
This call uses a specialised week-per-month pattern.
DECLARE @ColumnUpdatePattern varchar(1000) = 'Fiscal_year={year}, Fiscal_quarter={q}, ' + 'Fiscal_period={m}, Fiscal_Week={w}, ' + 'Fiscal_week_overall_nbr=(1161 + {w}), Fiscal_period_overall_nbr=(1037 + {m}), ' + '[quarter_Fiscal_of_year_end_date_key] = {qend}'; EXEC ai_GenerateFiscalCalendar @FirstDayOfFiscalYear='2017-04-30', @FiscalYearName = '2017', @TableToUpdate = 'dbo.DimDate', @DateKeyColumn = 'date_key', @ColumnUpdatePattern = @ColumnUpdatePattern, @WeeksPerMonthPattern = '4,4,5,4,4,5,4,5,4,4,4,5';
A summary is output to the messages tab so that the periods can be checked.
FISCAL YEAR: 2017 START DATE: 2017-04-30 Sunday TOTAL DAYS: 364 TOTAL WEEKS: 52 MONTHS: 1 2017-04-30 Sun 28 days 4 weeks Qtr: 1 Sem: 1 2 2017-05-28 Sun 28 days 4 weeks Qtr: 1 Sem: 1 3 2017-06-25 Sun 35 days 5 weeks Qtr: 1 Sem: 1 4 2017-07-30 Sun 28 days 4 weeks Qtr: 2 Sem: 1 5 2017-08-27 Sun 28 days 4 weeks Qtr: 2 Sem: 1 6 2017-09-24 Sun 35 days 5 weeks Qtr: 2 Sem: 1 7 2017-10-29 Sun 28 days 4 weeks Qtr: 3 Sem: 2 8 2017-11-26 Sun 35 days 5 weeks Qtr: 3 Sem: 2 9 2017-12-31 Sun 28 days 4 weeks Qtr: 3 Sem: 2 10 2018-01-28 Sun 28 days 4 weeks Qtr: 4 Sem: 2 11 2018-02-25 Sun 28 days 4 weeks Qtr: 4 Sem: 2 12 2018-03-25 Sun 35 days 5 weeks Qtr: 4 Sem: 2
The update statements (output as rows) are created by simple concatenation of the TableToUpdate, ColumnUpdatePattern and DateKeyColumns specified. One update is created for each day in the fiscal year.
UPDATE dbo.DimDate SET Fiscal_year=2017, Fiscal_quarter=1, Fiscal_period=1, Fiscal_Week=1, Fiscal_week_overall_nbr=(1161 + 1), Fiscal_period_overall_nbr=(1037 + 1), [quarter_Fiscal_of_year_end_date_key] = 20170729 WHERE date_key = 20170430; -- 364 update statements generated.