/ Published in: SQL
URL: http://blog.pengoworks.com/index.cfm/2009/1/7/Dynamically-generating-a-table-of-dates-in-MSSQL-2005
I did not write this. Simple UDF to generate all date/times between 2 given date/times
Expand |
Embed | Plain Text
CREATE FUNCTION generateDateTable ( -- Add the parameters for the function here @start_date datetime , @end_date datetime , @datepart varchar(20) = 'day' , @step int = 1 ) returns @dates TABLE ( -- Add the column definitions for the TABLE variable here start_date datetime, end_date datetime ) AS begin -- if we're doing calculations based on the days (not time) then strip the time out IF( @datepart IN ('year', 'yy', 'yyyy', 'quarter', 'qq', 'q', 'month', 'mm', 'm', 'dayofyear', 'dy', 'y', 'day', 'dd', 'd', 'week', 'wk', 'ww') ) begin SET @start_date = cast(floor(cast(@start_date AS float)) AS datetime) SET @end_date = cast(floor(cast(@end_date AS float)) AS datetime) end declare @new_start datetime while @start_date <= @end_date begin -- get the new starting row SET @new_start = (case when @datepart IN ('year', 'yy', 'yyyy') then dateadd(yy, @step, @start_date) when @datepart IN ('quarter', 'qq', 'q') then dateadd(qq, @step, @start_date) when @datepart IN ('month', 'mm', 'm') then dateadd(mm, @step, @start_date) when @datepart IN ('dayofyear', 'dy', 'y') then dateadd(dy, @step, @start_date) when @datepart IN ('day', 'dd', 'd') then dateadd(dd, @step, @start_date) when @datepart IN ('week', 'wk', 'ww') then dateadd(ww, @step, @start_date) when @datepart IN ('hour', 'hh') then dateadd(hh, @step, @start_date) when @datepart IN ('minute', 'mi', 'n') then dateadd(n, @step, @start_date) when @datepart IN ('second', 'ss', 's') then dateadd(s, @step, @start_date) when @datepart IN ('millisecond', 'ms') then dateadd(ms, @step, @start_date) else dateadd(dd, @step, @start_date) end) -- insert a new row INSERT @dates ( start_date , end_date ) VALUES ( @start_date -- since MSSQL is only accurate to 3.33ms, we need to subtract 3 ms to get the upper range in time , dateadd(ms, -3, @new_start) ) -- update the starting row SET @start_date = @new_start end RETURN end SELECT * FROM dbo.generateDateTable('12-01-2008', '12-31-2008', 'day', 1) /* Since the UDF uses a CTE to generate the data, if you're trying to output a resultset that produces more than 100 rows, you'll want to use the OPTION directive to set the maximum recursion number to use. This is only required if your output would generate more than 100 records. */ OPTION (maxrecursion 32767)
You need to login to post a comment.
