我有一张表,birthdate
里面有一个字段。我需要能够随机化日期和月份,但保留年份。这在 TSQL 中可能吗?
也就是说,如果该字段中的给定日期是 2012 年 1 月 1 日,我想要类似的内容:
RANDBETWEEN(1, 29) / RANDBETWEEN(1, 12) / 2012
我有一张表,birthdate
里面有一个字段。我需要能够随机化日期和月份,但保留年份。这在 TSQL 中可能吗?
也就是说,如果该字段中的给定日期是 2012 年 1 月 1 日,我想要类似的内容:
RANDBETWEEN(1, 29) / RANDBETWEEN(1, 12) / 2012
您可以采用这种方法,它不会分别随机化月份和日期,而是为您提供一个可以附加到年份的随机日期。
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');
以下是 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);
可能是这样的
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)
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