2012-07-08 94 views

回答

9

假設

首先,假設你有一個包含數據庫表中包含開始日期時間列和結束日期時間列,它們一起定義日期時間範圍E:

CREATE DATABASE StackOverflow11387226; 
GO 

USE StackOverflow11387226; 
GO 

CREATE TABLE DateTimeRanges (
    StartDateTime DATETIME NOT NULL, 
    EndDateTime DATETIME NOT NULL 
); 
GO 

ALTER TABLE DateTimeRanges 
ADD CONSTRAINT CK_PositiveRange CHECK (EndDateTime > StartDateTime); 

,並假定表包含一些數據:

INSERT INTO DateTimeRanges (
    StartDateTime, 
    EndDateTime 
) 
VALUES 
    ('2012-07-09 00:30', '2012-07-09 01:30'), 
    ('2012-01-01 00:00', '2013-01-01 00:00'), 
    ('1988-07-25 22:30', '2012-07-09 00:30'); 
GO 

方法

以下SELECT語句返回開始日期時間,結束日期時間,並與分精度的僞隨機日期時間大於或等於開始日期時間並小於第二個日期時間:

SELECT 
    StartDateTime, 
    EndDateTime, 
    DATEADD(
    MINUTE, 
    ABS(CHECKSUM(NEWID())) % DATEDIFF(MINUTE, StartDateTime, EndDateTime) + DATEDIFF(MINUTE, 0, StartDateTime), 
    0 
) AS RandomDateTime 
FROM DateTimeRanges; 

結果

因爲NEWID()函數是非確定性的,所以這將爲每次執行返回不同的結果集。這是我剛纔生成的結果集:

StartDateTime   EndDateTime    RandomDateTime 
----------------------- ----------------------- ----------------------- 
2012-07-09 00:30:00.000 2012-07-09 01:30:00.000 2012-07-09 00:44:00.000 
2012-01-01 00:00:00.000 2013-01-01 00:00:00.000 2012-09-08 20:41:00.000 
1988-07-25 22:30:00.000 2012-07-09 00:30:00.000 1996-01-05 23:48:00.000 

所有在列的startDateTime和EndDateTime值之間的列RandomDateTime謊言值。

說明

這種產生隨機值的技術是由於Jeff Moden引起的。他上的SQL Server中央寫了great article有關數據生成。閱讀它以獲得更全面的解釋。需要註冊,但它非常值得。

的想法是生成一個隨機從一開始日期時間偏移,並添加偏移量開始日期時間的開始日期時間和結束日期時間之間獲得一個新的日期時間。

表達DATEDIFF(MINUTE, StartDateTime, EndDateTime)表示開始日期時間和結束日期時間之間的分鐘總數。偏移量必須小於或等於此值。

表達ABS(CHECKSUM(NEWID()))產生用於每一行的獨立隨機正整數。該表達式可以具有從0到2,147,483,647的任何值。這個表達式第一個表達式給出了一個有效的偏移量,以分鐘爲單位

epxression DATEDIFF(MINUTE, 0, StartDateTime)表示開始日期時間和參考日期時間之間的總分鐘數0,這是'1900-01-01 00:00:00.000'的簡寫。引用日期時間的值並不重要,但重要的是在整個表達式中使用相同的引用日期。將其添加到偏移量以獲取參考日期時間之間的總分鐘數。

通過將前一個表達式生成的分鐘數添加到引用日期時間,生態封裝DATEADD函數將其轉換爲日期時間值。

+0

非常好地完成和代碼的偉大的總結。並感謝榮譽提及。對此,我真的非常感激。 – 2012-10-10 03:25:04

+0

@JeffModen沒問題。感謝您發佈您的方法! – 2012-10-10 08:58:40

8

您可以使用RAND此:

select cast(cast(RAND()*100000 as int) as datetime) 

here

SQL的小提琴看起來相當不錯:http://sqlfiddle.com/#!3/b9e44/2/0

+0

嗨時間,對不起,我忘了提及它需要在2日期之間 – 2012-07-08 22:58:50

+1

@Developer:[鏈接](http://www.sqlservercentral.com/Forums/Topic499265-8-1.aspx#bm501386)我我們提供了一個方法來指定一個範圍(找到乘數:'Select cast(cast('1 Jan 2010'as datetime)as int)')。 – 2012-07-09 07:25:01