Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate a resultset of incrementing dates in TSQL

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.

like image 232
p.campbell Avatar asked Sep 25 '09 18:09

p.campbell


People also ask

How do you create a date range in SQL?

Option 1: Create a table that holds long number sequence. The first approach is to create a long table with approx 1500 records (which can generate a date range for 3 years) off course you can adjust the number as you want, but in most cases you will not need more than one year so even 500 records are sufficient.

What is top1 in SQL?

The SQL SELECT TOP ClauseThe SELECT TOP clause is used to specify the number of records to return. The SELECT TOP clause is useful on large tables with thousands of records. Returning a large number of records can impact performance. Note: Not all database systems support the SELECT TOP clause.

How do I split a date range into a month in SQL?

type='p' and years. number between 100 and 150 -- note: 100-150 creates dates in the year range 2000-2050 -- adjust as required ) select dateadd(m,datediff(m, 0, d. thedate),0) themonth, count(1) from dates d join basis r on d.

How do you increment a column in SQL?

The MS SQL Server uses the IDENTITY keyword to perform an auto-increment feature. In the example above, the starting value for IDENTITY is 1, and it will increment by 1 for each new record. Tip: To specify that the "Personid" column should start at value 10 and increment by 5, change it to IDENTITY(10,5) .


1 Answers

If your dates are no more than 2047 days apart:

declare @dt datetime, @dtEnd datetime set @dt = getdate() set @dtEnd = dateadd(day, 100, @dt)  select dateadd(day, number, @dt) from      (select number from master.dbo.spt_values      where [type] = 'P'     ) n where dateadd(day, number, @dt) < @dtEnd 

I updated my answer after several requests to do so. Why?

The original answer contained the subquery

 select distinct number from master.dbo.spt_values      where name is null 

which delivers the same result, as I tested them on SQL Server 2008, 2012, and 2016.

However, as I tried to analyze the code that MSSQL internally when querying from spt_values, I found that the SELECT statements always contain the clause WHERE [type]='[magic code]'.

Therefore I decided that although the query returns the correct result, it delivers the correct result for wrong reasons:

There may be a future version of SQL Server which defines a different [type] value which also has NULL as values for [name], outside the range of 0-2047, or even non-contiguous, in which case the result would be simply wrong.

like image 200
devio Avatar answered Sep 28 '22 04:09

devio