For my data warehouse, I am creating a calendar table as follows:
SET NOCOUNT ON
DROP Table dbo.Calendar
GO
Create Table dbo.Calendar
(
CalendarId Integer NOT NULL,
DateValue Date NOT NULL,
DayNumberOfWeek Integer NOT NULL,
NameOfDay VarChar (10) NOT NULL,
NameOfMonth VarChar (10) NOT NULL,
WeekOfYear Integer NOT NULL,
JulianDay Integer NOT NULL,
USAIsBankHoliday Bit NOT NULL,
USADayName VarChar (100) NULL,
)
ALTER TABLE dbo.Calendar ADD CONSTRAINT
DF_Calendar_USAIsBankHoliday DEFAULT 0 FOR USAIsBankHoliday
GO
ALTER TABLE dbo.Calendar ADD CONSTRAINT
DF_Calendar_USADayName DEFAULT '' FOR USADayName
GO
Declare @StartDate DateTime = '01/01/2000'
Declare @EndDate DateTime = '01/01/2020'
While @StartDate < @EndDate
Begin
INSERT INTO dbo.Calendar
(
CalendarId,
DateValue,
WeekOfYear,
DayNumberOfWeek,
NameOfDay,
NameOfMonth,
JulianDay
)
Values
(
YEAR (@StartDate) * 10000 + MONTH (@StartDate) * 100 + Day (@StartDate), --CalendarId
@StartDate, -- DateValue
DATEPART (ww, @StartDate), -- WeekOfYear
DATEPART (dw, @StartDate), -- DayNumberOfWeek
DATENAME (dw, @StartDate), -- NameOfDay
DATENAME (M, @StartDate), -- NameOfMonth
DATEPART (dy, @StartDate) -- JulianDay
)
Set @StartDate += 1
End
--=========================== Weekends
-- saturday and sunday
UPDATE dbo.Calendar SET USAIsBankHoliday = 1, USADayName += 'Weekend, ' WHERE DayNumberOfWeek IN (1, 7)
--=========================== Bank Holidays
-- new years day
UPDATE dbo.Calendar SET USAIsBankHoliday = 1, USADayName += 'New Year''s Day, ' WHERE (CalendarId % 2000) IN (101)
-- memorial day (last Monday in May)
UPDATE dbo.Calendar
SET USAIsBankHoliday = 1,
USADayName += 'Memorial Day, '
WHERE 1=1
AND CalendarId IN
(
SELECT MAX (CalendarId)
FROM dbo.Calendar
WHERE MONTH (DateValue) = 5
AND DATEPART (DW, DateValue)=2
GROUP BY YEAR (datevalue)
)
-- independence day
UPDATE dbo.Calendar SET USAIsBankHoliday = 1, USADayName += 'Independence Day, ' WHERE (CalendarId % 2000) IN (704)
-- labor day (first Monday in September)
UPDATE dbo.Calendar
SET USAIsBankHoliday = 1,
USADayName += 'Labor Day, '
WHERE 1=1
AND CalendarId IN
(
SELECT MIN (CalendarId)
FROM dbo.Calendar
WHERE MONTH (DateValue) = 9
AND DATEPART (DW, DateValue)=2
GROUP BY YEAR (datevalue)
)
-- thanksgiving day (fourth Thursday in November)
UPDATE dbo.Calendar
SET USAIsBankHoliday = 1,
USADayName += 'Thanksgiving Day, '
WHERE 1=1
AND CalendarId IN
(
SELECT Max (CalendarId)-2
FROM dbo.Calendar
WHERE MONTH (DateValue) = 11
AND DATEPART (DW, DateValue)=7
GROUP BY YEAR (datevalue)
)
-- christmas
UPDATE dbo.Calendar SET USAIsBankHoliday = 1, USADayName += 'Christmas Day, ' WHERE (CalendarId % 2000) IN (1225)
--=========================== Other named days
-- new years eve
UPDATE dbo.Calendar SET USADayName += 'New Year''s Eve, ' WHERE (CalendarId % 2000) IN (1231)
-- black friday (day after thanksgiving day)
UPDATE dbo.Calendar SET USADayName += 'Black Friday, ' WHERE CalendarId IN (SELECT CalendarId+1 From dbo.Calendar Where USADayName like '%Thanksgiving%')
-- christmas eve
UPDATE dbo.Calendar SET USADayName += 'Christmas Eve, ' WHERE (CalendarId % 2000) IN (1224)
-- boxing day
UPDATE dbo.Calendar SET USADayName += 'Boxing Day, ' WHERE (CalendarId % 2000) IN (1226)
--=========================== Remove trailing comma
UPDATE dbo.Calendar SET USADayName = SubString (USADayName, 1, LEN (USADayName) -1) WHERE LEN (USADayName) > 2
SELECT * FROM dbo.Calendar
Here is the output of this command
I have seen similar structures implemented in various flavours by data architects.
My question is: What other data warehousing / dimension style useful information can I add to this table structure?
03 Mar CALENDAR TABLES IN T-SQL The basic concept behind a Calendar table is that each row is a date and the columns in the table represent complex date calculations that otherwise you'd need to perform manually in your query.
The calendar table is used extensively in reporting to generate weekly / monthly /quarterly reports. To build a calendar table, you don't have to start from scratch, you can use the below query to build a Calendar table in Snowflake. There is also now a calendar table available in the Snowflake Data Marketplace.
This is my list of possible columns in calendar dimension:
I created interactive spreadsheet where you can create your own time dimension for PostgreSQL database.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With