在sql中随机化现有日期的日期和月份

时间:2013-07-09 20:56:07

标签: sql sql-server tsql sql-server-2005

我的桌子里面有一个birthdate字段。我需要能够随机化日期和月份,但保持年份。这在TSQL中是否可行?

也就是说,如果字段中的给定日期是2012年1月1日,我想要像:

RANDBETWEEN(1, 29) / RANDBETWEEN(1, 12) / 2012

4 个答案:

答案 0 :(得分:3)

你可以采用这种方法,它不是单独随机分配月份和日期,而是给你随机的一天,你可以附加到你的一年。

DECLARE @year INT = 2012;
SELECT DATEADD(DAY, FLOOR(RAND() * 365), CAST(@year AS CHAR(4)) + '-01-01')

如果您需要对随机化进行闰年检查以包含12/31/LeapYear,则可以使用此代码:

DECLARE @year INT = 2012;
DECLARE @daysToAdd INT = 365;

IF @year % 400 = 0
   OR
   ( 
      @year % 100 != 0
      AND @year % 4 = 0
   )
BEGIN
   SELECT @daysToAdd = 366;
END

SELECT DATEADD(DAY,FLOOR(RAND() * @daysToAdd),CAST(@year AS CHAR(4)) + '-01-01');

答案 1 :(得分:1)

以下是2012年使用NEWID()和CRYPT_GEN_RANDOM()函数的两种方法。

SELECT RandomDateUsingNewId = DATEADD(DAY, ABS(CHECKSUM(NEWID())) % 366, '1/1/2012')
    , RandomDateUsingCryptGenRandom = DATEADD(DAY, CONVERT(INT, CRYPT_GEN_RANDOM(2)) % 366, '1/1/2012');

如果您希望代码在我们没有闰年(而不仅仅是2012年)的情况下工作多年,那么这里有一组经过修改的代码,可根据所选年份计算一年中的天数。

DECLARE @Year INT = 2012;
DECLARE @StartingDateOfYear DATE = CONVERT(DATE, CONCAT('1/1/', @Year));
DECLARE @DaysInYear INT = DATEPART(DAYOFYEAR, DATEADD(DAY, -1, DATEADD(YEAR, 1, @StartingDateOfYear)));

SELECT RandomDateUsingNewId = DATEADD(DAY, ABS(CHECKSUM(NEWID())) % @DaysInYear, @StartingDateOfYear)
    , RandomDateUsingCryptGenRandom = DATEADD(DAY, CONVERT(INT, CRYPT_GEN_RANDOM(2)) % @DaysInYear, @StartingDateOfYear);

答案 2 :(得分:0)

这样的事可能

WITH cte AS
(
  SELECT CAST('2012-01-01' AS DATE) ShortDate
  UNION ALL
  SELECT DATEADD(D, 1, ShortDate)
  FROM cte
  WHERE ShortDate < '2012-12-31'
)

SELECT TOP 10 ShortDate
FROM cte
ORDER BY NEWID()
OPTION (MAXRECURSION 0)

答案 3 :(得分:0)

declare @t table(birthdate date)
insert @t values('20130101'), ('20120505')

update t
set birthdate = v.newbirthdate
from @t t
cross apply
(
 select top 1
 dateadd(year, datediff(year, 0,t.birthdate), number) newbirthdate 
 from master..spt_values
 where type = 'P' and
 number < datepart(dayofyear, dateadd(year, datediff(year, -1,t.birthdate), -1))
 order by newid()
) v

select * from @t