如何使用随机日期更新行


69

我有一个简单的SQL表,其中有一个DateTime列。我想用随机日期更新所有行(> 100000行)。有一种简单的方法可以执行此SQL查询吗?

Answers:


90

使用它来生成1900年1月1日至2079年6月6日之间的smalldatetime(未选中,未安装SQL)

DATEADD(day, (ABS(CHECKSUM(NEWID())) % 65530), 0)

最好使用NEWID,然后再尝试使用RAND:RAND不会在单个SELECT或UPDATE中生成不同的值行(在SQL 2000中,如果行为已更改,则不会生成)。

编辑:像这样

UPDATE
  table
SET
  datetimecol = DATEADD(day, (ABS(CHECKSUM(NEWID())) % 65530), 0)

编辑:将65535更改为65530,并添加了ABS,以避免超出范围上限


聪明!在SQL Server 2000上为我工作。创建表#test(d datetime); 插入#test值(空);插入#test值(空);插入#test值(空);更新#test SET d = DATEADD(day,(ABS(CHECKSUM(NEWID()))%65530),0); 从#test中选择*;删除表#test;
Patrick McElhaney 09年

请问,为什么电话号码是65530?怎么算呢?
阿梅丽娜(Amelina)'17

@Amelina“将65535更改为65530,并添加了ABS,以避免在范围上限时溢出”
gbn

是的,我明白了。我没有如何计算不同范围的数据。是65530秒,毫秒还是?
Amelina '17

1
@Amelina这些是最长的天数。如果执行此操作select dateadd(day,65530,0),它将结束于2079-06-01。
桑德

64

我将补充以下答案,

SELECT DATEADD(DAY, ABS(CHECKSUM(NEWID()) % 3650), '2000-01-01')
FROM your_table

这会生成从2000年1月1日开始的日期,您可以更改模数值的天数,我输入3650(约10年),这种方法不会溢出。

如果要更新,那么

UPDATE your_table
SET your_date_field = DATEADD(DAY, ABS(CHECKSUM(NEWID()) % 3650), '2000-01-01')
WHERE your_conditions

2
是的,我有一个错误。CHECKSUM生成带符号的32位整数,因此我添加了ABS
gbn

40

这个问题似乎很老了,但我的回答可能对其他人有用。

      Update table
      SET Time= DateAdd(d, ROUND(DateDiff(d, '2010-01-01', '2013-12-31') * RAND(CHECKSUM(NEWID())), 0),
      DATEADD(second,CHECKSUM(NEWID())%48000, '2010-01-01'))

这将在给定范围之间生成一个随机的日期时间。


真是的 很好 爱它。
2015年

不错的解决方案RAND(CHECKSUM(NEWID()))-我正在RANK() OVER对日期进行排序,但是由于数据输入错误(出于我的控制),有两行具有完全相同的日期,并且随后获得了相同的排名,而该行应该具有一个分别为1和2。
puiu

8

我改写了上述Jhonny的答案,以获取过去10年的日期:

SELECT dateadd(day, (abs(CHECKSUM(newid())) % 3650) * -1, getdate())

请注意,这仅是SQLServer。


5

以下代码将使用两个给定日期之间的随机日期填充FiscalYear表的StartDate列:

-- First, let's declare the date range.
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 = '1985-10-14';
SET @date_to = '2009-04-27';

UPDATE FiscalYear SET StartDate =  
(
    -- 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 >= 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)
    )
)

1
这为每一行生成不同的日期。
CSharper

为什么不使用DATEADD和DATEDIFF?
gbn

5

我用它为所有测试数据设定了1940年至1985年之间的出生日期

SET [Birth Date] = DATEADD(day, (ABS(CHECKSUM(NEWID())) % 16250), '1940-1-1 00:00:00.001')

2

我一直在寻找与此类似的问题,该问题也产生了随机时间,所以我找到了这个脚本。认为这里可能有用:

DECLARE @DateFrom DATETime = '2001-01-01'
DECLARE @DateTo DATeTime = '2013-11-30'
DECLARE @DaysRandom Int= 0
DECLARE @MillisRandom Int=0

--get random number of days

select @DaysRandom= DATEDIFF(day,@DateFrom,@DateTo)
SELECT @DaysRandom = ROUND(((@DaysRandom -1) * RAND()), 0)

--get random millis
SELECT @MillisRandom = ROUND(((99999999) * RAND()), 0)

SELECT @DateTo = DATEADD(day, @DaysRandom, @DateFrom)
SELECT @DateTo = DATEADD(MILLISECOND, @MillisRandom, @DateTo)
SELECT @DateTo

我从这里得到的:http : //crodrigues.com/sql-server-generate-random-datetime-within-a-range/


1

您可以尝试获取随机数(正数或负数),然后将该数字添加到日期(可能是系统日期)中。

例如(我现在无法访问sqlserver,因此无法验证语法)

DATEADD(day, DATEDIFF(day, 0, GETDATE()) - 1 - FLOOR(RAND(CAST(NEWID() AS binary(4))) * 365.25 * 90), 0)

在SQL Server 2019(10年后)中,这确实适用于多行。SELECT DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) - 1 - FLOOR(RAND(CAST(NEWID() AS BINARY(4))) * 365.25 * 90), 0), ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n)
Nielsvh

0

使用下面的代码,您可以获取@Min(1)和@Max(365)之间的随机整数,然后使用dateadd函数可以创建去年的随机日期。

CREATE VIEW vRandNumber
AS
SELECT RAND() as RandNumber
GO

CREATE FUNCTION RandNumber(@Min int, @Max int)
RETURNS int
AS
 BEGIN
 RETURN round(@Min + (select RandNumber from vRandNumber) * (@Max-@Min),0)
 END
GO

Update table1
set theDate = dateadd(d,0-dbo.RandNumber(1,365),getdate())

udf可能会使RAND每行不同。我明天会尝试
gbn

0

我为自己组合了几个答案,我认为它对您有用。我花了40秒钟执行了140k行。i5、1333MHZ,标准笔记本硬盘

 DECLARE @rank INT = 0;

WHILE @rank < yourmaxrow --(you can use Select count (*) from your table name as well)
BEGIN
   DECLARE @FromDate DATETIME = DATEADD(DAY, -720, GETDATE()) -- 2 years back
   DECLARE @ToDate   DATETIME = DATEADD(DAY, -1, GETDATE()) -- until yesterday

   DECLARE @Seconds INT = DATEDIFF(SECOND, @FromDate, @ToDate)
   DECLARE @Random INT = ROUND(((@Seconds-1) * RAND()), 0)
   DECLARE @Milliseconds INT = ROUND((999 * RAND()), 0)

update yourtablename
Set yourdatetiemcolumnname = DATEADD(MILLISECOND, @Milliseconds, DATEADD(SECOND, @Random, @FromDate))
WHERE Id = @rank
   SET @rank = @rank + 1;       
END;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.