I was writing an application today that needed a date dimension table and this was the script that i built. I don't know if this going to be useful to anybody.. anyway, my main purpose of putting it in my blog is so that i can just go to my site and do a copy-and-paste when the time comes that I need to use this script again.
First we need to build our table schema. My table schema required an ID column, a Date column, a Year column, a Month column and a Day column. All fields where of int data type except for the Date column. Below is how the script for creating the table looks like.
[STEP 1 - Create Table Schema.sql]
--#############################################################-- Author: Keith Rull-- Script Date: May 11. 2007-- Description: This script creates the table schmema for-- our date dimension table.--#############################################################IF EXISTS ( SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DateDimension]') AND type in (N'U') )DROP TABLE [dbo].[DateDimension]SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [dbo].[DateDimension]( [DateID] [int] IDENTITY(1,1) NOT NULL, [Date] [datetime] NOT NULL, [Year] [int] NOT NULL, [Month] [int] NOT NULL, [Day] [int] NOT NULL,CONSTRAINT [PK_DateDimension] PRIMARY KEY CLUSTERED ( [DateID] ASC)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]) ON [PRIMARY]
*NOTE: Please be careful when using this script. A drop table script is include on the first few lines of the file. Please delete it if you dont need to delete the existing date dimension table
I built two scripts for creating a date dimension table. The first script is designed to be use with SQL Server 2000(or earlier) but will still work with SQL Server 2005. I created it by using a while loop instead of using a cursor which an officemate of mine suggested because i didn't find any urgency to use cursors for this script. Below is the is the script I built:
[STEP 2 - POPULATE THE TABLE WITH DATES.sql]
--#############################################################-- Author: Keith Rull-- Script Date: May 11, 2007-- Description: Use this script if you are using SQL Server 2000 -- or earlier. This works with SQL Server 2005 too.--#############################################################--declare our date variablesDECLARE @LowerBoundDate DATETIMEDECLARE @UpperBoundDate DATETIMEDECLARE @IteratingDate DATETIME--set the initial datesSET @LowerBoundDate = '1/1/1980'SET @UpperBoundDate = '1/1/2040'--create our temporary tableDECLARE @TempDateDimension TABLE ( Date DATETIME , [Year] INT , [Month] INT , [Day] INT)--set the iterating date to the lowerbound dateSET @IteratingDate = @LowerBoundDate--continue to loop until our iterating date is the same as the target dateWHILE @IteratingDate <= @UpperBoundDateBEGIN --insert the date to our temporary table INSERT @TempDateDimension ( Date , [Year] , [Month] , [Day] ) VALUES ( @IteratingDate , Year(@IteratingDate) , Month(@IteratingDate) , Day(@IteratingDate) ) --increase the value of our iterating date SET @IteratingDate = @IteratingDate + 1END--Insert the dates to our permanent Dimension tableINSERT INTO dbo.DateDimensionSELECT Date , [Year] , [Month] , [Day]FROM @TempDateDimension--View the contents of the tableSELECT Date , [Year] , [Month] , [Day]FROM dbo.DateDimension WITH(NOLOCK)
The script above expects you to change the start and end date. What the script does is that it iterates from a lowerbound date to an upperbound date and inserts those dates into our DateDimension table. Pretty slick huh?
What's cooler is that you can do the same script without using a while loop(or cursors) with one the new features of SQL Server 2005 called Common Table Expressions. The resulting script would look like this:
[STEP 2 - POPULATE THE TABLE WITH DATES(SQL 2005).sql]
--#############################################################-- Author: Keith Rull-- Script Date: May 11, 2007-- Description: Use this script if you want to use the new -- SQL Server 2005 featured called Commong Table Expressions.-- This script only works with SQL Server 2005--#############################################################--declare our date variablesDECLARE @LowerBoundDate DATETIMEDECLARE @UpperBoundDate DATETIME--set the initial datesSET @LowerBoundDate = '1/1/1980';SET @UpperBoundDate = '1/1/2040';--create our temporary tableDECLARE @TempDateDimension TABLE ( Date DATETIME , [Year] INT , [Month] INT , [Day] INT);--use CTE to create our date iterator WITH CalculatedDate AS(SELECT @LowerBoundDate DateUNION ALLSELECT (Date + 1)FROM CalculatedDate WHERE ((Date + 1) <= @UpperBoundDate)) --insert each date to our temporay dimension table INSERT INTO @TempDateDimension SELECT Date , Year(Date) AS [Year] , Month(Date) AS [Month] , Day(Date) AS Day FROM CalculatedDateOPTION (MAXRECURSION 0)--Insert the dates to our permanent Dimension tableINSERT INTO dbo.DateDimensionSELECT Date , [Year] , [Month] , [Day]FROM @TempDateDimension--View the contents of the tableSELECT Date , [Year] , [Month] , [Day]FROM DateDimension WITH(NOLOCK)
Sweet! It looks confusing at first but once you get use to it(and know whole nine yards about CTE) you'll find how great CTE of a help can be to you in your SQL projects.
I hope this helps someone with a similar dilema that I had to day.
Get the scripts here: Date Dimension Table.zip | Date Dimension Table(using CTE).zip
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.