Consider the need to create a resultset of dates. We've got start and end dates, and we'd like to generate a list of dates in between.
DECLARE @Start datetime
,@End datetime
DECLARE @AllDates table
(@Date datetime)
SELECT @Start = 'Mar 1 2009', @End = 'Aug 1 2009'
--need to fill @AllDates. Trying to avoid looping.
-- Surely if a better solution exists.
Consider the current implementation with a WHILE
loop:
DECLARE @dCounter datetime
SELECT @dCounter = @Start
WHILE @dCounter <= @End
BEGIN
INSERT INTO @AllDates VALUES (@dCounter)
SELECT @dCounter=@dCounter+1
END
Question: How would you create a set of dates that are within a user-defined range using T-SQL? Assume SQL 2005+. If your answer is using SQL 2008 features, please mark as such.
For this method to work, you need to do this one time table setup:
Once the Numbers table is set up, use this query:
to capture them do:
output:
@KM's answer creates a numbers table first, and uses it to select a range of dates. To do the same without the temporary numbers table:
Test of course, if you are doing this often, a permanent table may well be more performant.
The query above is a modified version from this article, which discusses generating sequences and gives many possible methods. I liked this one as it does not create a temp table, and is not limited to the number of elements in the
sys.objects
table.Another option is to create corresponding function in .NET. Here's how it looks like:
This is basically a prototype and it can be made a lot smarter, but illustrates the idea. From my experience, for a small to moderate time spans (like a couple of years) this function performs better than the one implemented in T-SQL. Another nice feature of CLR version is that it does not creates temporary table.
Tthe following uses a recursive CTE (SQL Server 2005+):
The best answer is probably to use the CTE, but there is no guarantee you are able to use that. In my case, I had to insert this list inside an existing query created dinamically by a query generator...couldn't use CTE nor stored procedures.
So, the answer from Devio was really useful, but I had to modify it to work in my environment.
In case you don't have access to the master db, you may use another table in your database. As for the example before, the maximum date range is given by the number of rows inside the table choosen.
In my example tough, using the row_number, you can use tables without an actual int column.
Overview
Here's my version (2005 compatible). The advantages of this approach are:
SQL Fiddle: http://sqlfiddle.com/#!6/c3896/1
Code
A reusable function for generating a range of numbers based on given parameters:
Putting this to use for your scenario:
2005 Compatible