Ask Ben: Getting A Random Date From A Date Range In SQL

Posted October 3, 2006 at 7:44 AM by Ben Nadel

Tags: SQL, Ask Ben

How can I select a random date from a date range in SQL server. I basically want to do RandRange() for dates in sql? Does that make sense?

I have to admit, this one totally stumped me at first. I rarely work with random data in SQL. If I need random data I usually just build a query in ColdFusion. I tried looking up random methods for SQL, but it turns out that things like RAND() are only called once per table, NOT per row. I got some great ideas from Jon Galloway over at http://weblogs.asp.net/jgalloway/archive/2004/03/18/92498.aspx. He supplied the way to come up with a random date:

  • cast(
  • cast( getdate() as int )
  • -5 * rand( cast( cast( newid() as binary(8) ) as int ) )
  • as datetime
  • )

I am not exactly sure what the casting of the UUID to a binary(8) does, but I see that it converts to an integer.

After some experimentation, I see that casting UUIDs to binary can result in either a negative or positive number. For a date range, I needed to work with a positive number. Therefor I use ABS() to force a positive outcome. Once we have that, all we need is the date range part. That's where our old friend date-math comes in. You can think of a random date from a date range as adding a random number of days to the start date (>= 0) such that the resultant date does not exceed the end range date.

Once you think about it that way, we have all the pieces we need:

  • -- First, let's declare the date range. I am declaring this
  • -- here for the demo, but this could be done anyway you like.
  • DECLARE @date_from DATETIME;
  • DECLARE @date_to DATETIME;
  •  
  • -- Set the start and date dates. In this case, we are using
  • -- the month of october, 2006.
  • SET @date_from = '2006-10-01';
  • SET @date_to = '2006-10-30';
  •  
  • -- Select random dates.
  • SELECT
  • (
  • -- Remember, we want to add a random number to the
  • -- start date. In SQL we can add days (as integers)
  • -- to a date to increase the actually date/time
  • -- object value.
  • @date_from +
  • (
  • -- This will force our random number to be GTE 0.
  • ABS(
  •  
  • -- This will give us a HUGE random number that
  • -- might be negative or positive.
  • CAST(
  • CAST( NewID() AS BINARY(8) )
  • AS INT
  • )
  • )
  •  
  • -- Our random number might be HUGE. We can't have
  • -- exceed the date range that we are given.
  • -- Therefore, we have to take the modulus of the
  • -- date range difference. This will give us between
  • -- zero and one less than the date range.
  • %
  •  
  • -- To get the number of days in the date range, we
  • -- can simply substrate the start date from the
  • -- end date. At this point though, we have to cast
  • -- to INT as SQL will not make any automatic
  • -- conversions for us.
  • CAST(
  • (@date_to - @date_from)
  • AS INT
  • )
  • )
  • )

Hope that helps.




Reader Comments

Jan 31, 2007 at 10:59 PM // reply »
1 Comments

Just wanted to say thanks for this post, it was exactly what I was after!

Cheers,

Steve.


Feb 1, 2007 at 7:39 AM // reply »
11,314 Comments

Steve,

Glad to help.


Nov 26, 2008 at 8:55 AM // reply »
3 Comments

Great post. Thanks a lot!


Nov 26, 2008 at 11:39 AM // reply »
3 Comments

Hey how about including a random time in that date time as well?


Nov 27, 2008 at 8:59 AM // reply »
3 Comments

This works as well.

select DATEADD(second, rand()*86400, DATEADD(d, rand()*(CAST((@date_to - @date_from) AS INT )), @date_from))

86400, being the number of seconds in a day.

Cheers.


Feb 10, 2009 at 1:21 PM // reply »
1 Comments

Thanks! This script helped me a lot in trying to generate a buncha test data where we're tracking stats based on unique datetimes.


Mar 29, 2009 at 8:24 PM // reply »
1 Comments

Nice code and great explanation.

Thank you for that.


CRH
Jul 7, 2009 at 1:48 PM // reply »
1 Comments

Here's a slightly modified version... selecting a random time during an 8hr period during a particular day. (28800 is the number of seconds in 8 hours.) I send the NEWID() through RAND() to guarantee a unique timestamp for each row.

DECLARE @date_from DATETIME;
DECLARE @date_to DATETIME;

SET @date_from = '2009-06-29 08:00:00.000';
SET @date_to = '2009-06-29 16:00:00.000';

SELECT DATEADD(second, RAND(ABS(CAST(CAST(NewID() AS BINARY(8)) AS INT)))*28800, DATEADD(d, RAND(ABS(CAST(CAST(NewID() AS BINARY(8)) AS INT)))*(CAST((@date_to - @date_from) AS INT )), @date_from))


Jul 7, 2009 at 6:15 PM // reply »
11,314 Comments

@CRH,

That's a cool idea. A bit hard to read here, but I think I get the point.


RXA
Sep 3, 2009 at 2:01 PM // reply »
1 Comments

How would I add random seconds to each row in MS Access


Sep 25, 2009 at 10:50 AM // reply »
1 Comments

Very good code. It worked fine, the only thing that I have to check is the Date Format, as my SQL Server 2005 is in Portuguese I had to change the format to YYYY-DD-MM

Thank you


Aug 22, 2010 at 5:59 AM // reply »
1 Comments

I did it like that

random date betweem 1-9-2009 to 29-1-2010
(between 0 to 150 days)

DECLARE @RandomNumber float
DECLARE @RandomDayF int
DECLARE @MaxDay int
DECLARE @MinDay int

SET @MaxDay = 150
SET @MinDay = 0

-- random the number of days to add
SELECT @RandomNumber = RAND()

set @randomDayF = ((@MaxDay + 1) - @MinDay) * @RandomNumber + @MinDay

-- add the days
Set @FromDate = (select DATEADD(d, @randomDayF,(SELECT convert(datetime, '1-9-2009',105)))) -- dd-mm-yyyy

--to reduce days
-- @randomDayF = @randomDayF * -1


Dec 17, 2010 at 6:01 AM // reply »
1 Comments

Wow- awesome work guys , it has helped me alot..
Abbi


Apr 1, 2012 at 4:19 AM // reply »
1 Comments

Hi Ben,

thank you very much!!

Best reagds,
Steven


Dec 7, 2012 at 8:32 AM // reply »
1 Comments

I used this sample to generate random number from 1 to 1000000000
amazingly it produce 9-digit most of the time

I want it to generate more like 1,2,3,..9-digit

actually I need it in a lottery app
any other suggestion I'll appreciate it



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Jun 18, 2013 at 9:20 PM
Mapping AngularJS Routes Onto URL Parameters And Client-Side Events
I couldn't find examples of passing multiple arguments using the when() routing statement so figured out through trial and error that you can pass multiple arguments using the following format: .whe ... read »
Jun 18, 2013 at 3:39 PM
Experimenting With The Amazon Simple Storage Service (S3) API Using ColdFusion
Hi Ben, THANKS! While not bleeding edge, it is new to me & I like learning new things every day! ... read »
Jun 18, 2013 at 12:30 PM
Disabling Auto-Correct And Auto-Capitalize Features On iPhone Inputs
Also spellcheck="false" should be mentioned as part of html5 specs ... read »
Jun 18, 2013 at 8:40 AM
Using Named Functions Within Self-Executing Function Blocks In Javascript
Hi Ben, you forgot to mention the most important thing for named self-executing functions - they can be referenced by name ONLY inside their execution context (which is parens in this case), it mean ... read »
dee
Jun 18, 2013 at 7:01 AM
My Safari Browser SQLite Database Hello World Example
hai ben, this program is really good i could understand the concept but i dint know how to save it and how to open it as you have done in the video can u give that details pls ... read »
Jun 18, 2013 at 6:04 AM
Clearing Inline CSS Properties With jQuery
Thanks a lot for for post! It helped me a lot... after being stuck since 24 hrs.. found solution from your post. Thanks again! ... read »
Jun 18, 2013 at 2:31 AM
SOTR 2013 - The Best Conference I Never Went To
I keep watching it, should keep me happily distracted until SotR14 ;) ... read »
Jun 17, 2013 at 9:45 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, As I was reading what you wrote, it occurred to me that maybe I do something similar to that in some of my client-side code. In an application I'm working on, there are a bunch of unrelated ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools