TSQL更新日期时间,具有2个日期之间的随机值

时间:2012-07-08 22:26:21

标签: tsql datetime random

在TSQL上更新包含DATETIME列的表的最简单方法是什么?{2}日期之间的值为RANDOM

我看到与此相关的各种帖子,但在更新后ORDER BY DATE,他们的随机值确实是连续的。

2 个答案:

答案 0 :(得分:10)

假设

首先假设您有一个数据库,其中包含一个包含start datetime列和end datetime列的表,它们共同定义了一个日期时间范围:

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

RandomDateTime列中的所有值都位于StartDateTime和EndDateTime列中的值之间。

解释

这种用于生成随机值的技术归功于Jeff Moden。他在SQL Server Central上写了一篇关于数据生成的great article。阅读它以获得更全面的解释。注册是必需的,但这是值得的。

我们的想法是从开始日期时间生成一个随机偏移量,并将偏移量添加到开始日期时间,以便在开始日期时间和结束日期时间之间获得新的日期时间。

表达式DATEDIFF(MINUTE, StartDateTime, EndDateTime)表示开始日期时间和结束日期时间之间的总分钟数。偏移量必须小于或等于此值。

表达式ABS(CHECKSUM(NEWID()))为每一行生成一个独立的随机正整数。表达式可以具有0到2,147,483,647之间的任何值。这个表达式mod第一个表达式给出了一个有效的偏移量,以分钟为单位。

epxression DATEDIFF(MINUTE, 0, StartDateTime)表示开始日期时间与0的参考日期时间之间的总分钟数,它是'1900-01-01 00:00:00.000'的简写。引用日期时间的值无关紧要,但重要的是在整个表达式中使用相同的引用日期。将其添加到偏移量以获取参考日期时间之间的总分钟数。

ecapsulating DATEADD函数通过将前一个表达式产生的分钟数与参考日期时间相加,将其转换为日期时间值。

答案 1 :(得分:8)

您可以使用RAND

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

来自here

Sql-Fiddle看起来很不错:http://sqlfiddle.com/#!3/b9e44/2/0