我的桌子里面有一个birthdate
字段。我需要能够随机化日期和月份,但保持年份。这在TSQL中是否可行?
也就是说,如果字段中的给定日期是2012年1月1日,我想要像:
RANDBETWEEN(1, 29) / RANDBETWEEN(1, 12) / 2012
答案 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