创建 SQL 随机出生日期

4 sql-server data-masking

有没有人有任何 SQL 代码来自动生成随机出生日期,其中出生日期小于今天?请添加出生日期范围参数,例如:从 18 岁到 70 岁。

是否有任何内联 SQL 或函数来执行此操作?

我们正试图混淆我们的专栏[Date of Birth]

谢谢,

Han*_*non 23

这会将随机天数添加到 1900 年 1 月 1 日:

SELECT DATEADD(DAY, CONVERT(int, CRYPT_GEN_RANDOM(2)), '1900-01-01T00:00:00');
Run Code Online (Sandbox Code Playgroud)

根据 Microsoft Docs,CRYPT_GEN_RANDOM“返回由加密 API (CAPI) 生成的加密随机数。输出是指定字节数的十六进制数。”

因此CRYPT_GEN_RANDOM(2)返回一个在0x0000to范围内的两字节数字0xFFFF,当转换为有符号整数并“添加”到时1900-01-01,将导致在1900-01-01to范围内的日期2079-06-06

对于名为 的表dbo.MyTable,具有名为的列[Date of Birth],这会将所有列值更新为随机生成的日期:

UPDATE dbo.MyTable
SET [Date of Birth] = DATEADD(DAY, CONVERT(int, CRYPT_GEN_RANDOM(2)), '1900-01-01T00:00:00');
Run Code Online (Sandbox Code Playgroud)

你可以颠倒逻辑,这样你就有从 0 天到大约 59 岁的不同年龄的人:

UPDATE dbo.MyTable
SET [Date of Birth] = DATEADD(DAY, (1 - CONVERT(int, CRYPT_GEN_RANDOM(2)) / 3), GETDATE());
Run Code Online (Sandbox Code Playgroud)

以下示例将随机选择出生日期,导致年龄在 10 到 20 岁之间:

DECLARE @MinAge int;
DECLARE @MaxAge int;

SET @MinAge = 10;
SET @MaxAge = 20;
UPDATE dbo.MyTable
SET [Date of Birth] = DATEADD(DAY
    , (1 - (CONVERT(int, CRYPT_GEN_RANDOM(2)) % ((@MaxAge - @MinAge) * 365)))
    , CONVERT(date, DATEADD(YEAR, 1 - @MinAge, GETDATE()))
    );
Run Code Online (Sandbox Code Playgroud)


小智 8

方法一

select DATEADD(DAY, -(ABS(CHECKSUM(NEWID()) % 36500 )), getdate());
Run Code Online (Sandbox Code Playgroud)

示例输出:

1980-11-10 02:19:37.643
1940-08-25 02:20:06.217
1967-10-10 02:20:15.030
2013-03-20 02:20:24.933
1951-11-19 02:20:38.973

总而言之,以下代码生成 0 到 36500 之间的随机数。(36500 天大致等于 100 年;您可以使用36525使其恰好为100 年。)

ABS(CHECKSUM(NEWID()) % 36500 )
Run Code Online (Sandbox Code Playgroud)

通过将当前日期减去随机生成的数字(随机天数),您将能够获得年龄介于 0 到 100 岁之间的人的随机日期。

演示:http : //sqlfiddle.com/#!18/ 9eecb/ 15528/0

  

方法二

DECLARE @start DATE = '1980-01-01'
DECLARE @end DATE = '1980-01-05'

SELECT DATEADD(DAY,ABS(CHECKSUM(NEWID())) % DATEDIFF(DAY,@start,@end) ,@start)
Run Code Online (Sandbox Code Playgroud)

示例输出:

1980-01-01
1980-01-04
1980-01-03
1980-01-02

使用该DATEDIFF函数,您可以获得两个日期之间的差异。在这种情况下 ( DATEDIFF(DAY,@start,@end),开始日期和结束日期之间的差异将以天为单位。通过将此值添加到开始日期,您可以在开始日期和结束日期之间生成随机日期。

但是,这不会将结束日期 ( 1980-01-05) 作为随机生成的日期返回。为此,您可以将差值加 1。

SELECT DATEADD(DAY,ABS(CHECKSUM(NEWID())) % ( 1 + DATEDIFF(DAY,@start,@end)),@start)
Run Code Online (Sandbox Code Playgroud)

演示:http : //sqlfiddle.com/#!18/ 9eecb/ 15542/0

  

方法三

示例 1

SELECT DATEADD(DAY, RAND() * ((-36500) - 1), GETDATE())
Run Code Online (Sandbox Code Playgroud)

示例输出:

1956-02-25T23:44:17.62Z
2006-09-08T23:44:40.62Z
1987-06-13T23:44:53.717Z

示例 2

SELECT DATEADD(DAY, RAND() * ((-1) - 1), GETDATE())
Run Code Online (Sandbox Code Playgroud)

示例输出:

2018-05-03 06:32:56.753
2018-05-02 06:32:56.753

注意:如果去掉' - 1',2018-05-02 06:32:56.753将不会生成。

演示:http : //sqlfiddle.com/#!18/ 9eecb/ 15554/0

  

方法四

DECLARE @start DATE = '1980-01-01'
DECLARE @end DATE = '1980-01-05'

SELECT DATEADD(DAY, RAND() * DATEDIFF(DAY,@start,@end) ,@start)
Run Code Online (Sandbox Code Playgroud)

示例输出:

1980-01-02
1980-01-01
1980-01-03
1980-01-04

注意:这也不会将结束日期 ( 1980-01-05) 作为随机生成的日期返回。你知道你必须像这样加1。

DATEDIFF(DAY,@start,@end) +1
Run Code Online (Sandbox Code Playgroud)

演示:http : //sqlfiddle.com/#!18/ 9eecb/ 15538/0

  

方法五

DECLARE @from INT = 18 
DECLARE @to INT = 70 

DECLARE @tfrom DATE = DATEADD(YEAR, -(@from), GETDATE()) 
DECLARE @tto DATE = DATEADD(YEAR, -(@to), GETDATE()) 

DECLARE @diff INT = DATEDIFF(DAY, @tfrom, @tto)

SELECT DATEADD(DAY, RAND() * (-(@diff) - 1), @tto)
Run Code Online (Sandbox Code Playgroud)

示例输出:

1967-11-03
1955-10-09
1967-06-03
1962-11-17
1970-07-04

演示:http : //sqlfiddle.com/#!18/ 9eecb/ 15555/0