你好,以下是重构后的内容:

文章目录:

- 生成随机数字

- 生成 0 到 1 之间的随机数

- 生成指定范围内的随机数

- 生成 6 位数字手机验证码

- 生成遵循正态分布的随机数

- 生成随机字符串

- 生成固定长度的随机字符串

- 生成可变长度的随机字符串

- 生成随机日期和时间

- 生成 UUID

- 获取表中的随机记录

- 总结

大家好,我是只谈技术不剪发的 Tony 老师。

随机数对于我们而言并不陌生,例如手机短信验证码就是一个随机的数字字符串;对于统计分析、机器学习等领域而言,通常也需要生成大量的随机数据用于测试、数据抽样、算法验证等。那么今天我们就来介绍一下如何在 Microsoft SQL Server 中生成随机数据,包括随机数字、验证码、随机字符串以及随机日期和时间等。

如果觉得文章有用,欢迎评论📝、点赞👍、推荐🎁

📝计算机生成的都是伪随机数,并不是真正的物理随机数。

## 生成随机数字

### 生成 0 到 1 之间的随机数

RAND()

```sql

SELECT RAND() AS rd; rd | ------------------| 0.8186902226508435|

```

该函数返回的数据类型为 float,每次调用都会返回不同的结果。如果想要重现某些场景,需要确保每次运行时生成相同的随机数。这种情况下可以为 RAND 函数传递一个输入参数,设置一个随机数种子。例如:

```sql

SELECT RAND(1) AS rd; rd | ------------------| 0.7135919932129235|

```

从结果可以看出,设置相同的种子之后,函数返回了相同的随机数。

### 生成指定范围内的随机数

基于 RAND() 函数和一些运算,就可以返回任意两个数字之间的随机数:

low + RAND() * (high - low)

以上表达式将会返回一个大于 low,小于 high 的随机数。例如:

```sql

SELECT low + RAND() * (high - low) AS random_number;

```

以下是重构后的内容:

```sql

-- 生成大于10且小于20的随机数字

SELECT 10 + RAND() * 10 AS rd; rd | -----------------| 13.43443392823765|

-- 生成指定范围内的随机整数(例如大于等于10,小于20)

SELECT FLOOR(10 + RAND() * 10) AS rd; rd | ----| 17.0|

-- 生成由6位数字字符组成的手机验证码

SELECT RIGHT(CONCAT('000000',FLOOR(RAND()* 1000000)),6) AS captcha; captcha| -------| 925656 |

-- 生成遵循正态分布的随机数

-- 注意:这种方法可能在某些数据库中无法直接使用,因为它依赖于两个平均分布的随机数通过Box-Muller变换算法生成正态分布的随机数。

-- @stdev 是标准差,@mean 是均值。例如,以下查询生成了一个均值为0,标准差为1的正态分布随机数:

SELECT (sqrt(-2 * log(rand())) * cos(2 * pi() * rand())) * @stdev + @mean;

-- 我们可以验证一下这种方式生成的随机数是否遵循正态分布,例如:

```

以下是重构后的内容:

```sql

CREATE TABLE #t(val float);

BEGIN

DECLARE @counter INT = 1;

WHILE @counter <= 1000000 BEGIN

INSERT INTO #t

SELECT (sqrt(-2 * log(rand())) * cos(2 * pi() * rand())) * 1 + 0;

SET @counter = @counter + 1;

END;

END;

SELECT avg(val) as avg, stdev(val) as stdev FROM #t;

```

执行上述 SQL Server 代码会得到平均值和标准差非常接近 0 和 1。

```csharp

// C#代码生成随机字符串

Random rnd = new Random();

string str = "";

for (int i = 0; i < length; i++)

{

char ch = (char)rnd.Next('A', 'Z' + 1)); //生成大写字母

str += ch;

}

return str;

```

注意:以上C#代码中的length需要你根据实际需求来设定,例如你想生成一个长度为10的随机字符串,那么你应该将length设为10。

以下是重构后的代码:

```sql

-- 创建视图 v_rand,用于生成随机数

CREATE VIEW v_rand AS SELECT RAND() AS val;

-- 创建或修改函数 rand_num,接收一个整数参数 n,返回一个整数

CREATE OR ALTER FUNCTION rand_num(@n INT) RETURNS INT AS

BEGIN

SELECT @n = @n * val FROM v_rand;

RETURN @n;

END;

-- 创建或修改函数 random_string,接收两个参数:一个整数 num,表示要生成的随机字符串的长度;一个字符串 chars,表示用于生成随机字符串的字符集(默认为所有数字、大小写字母)

CREATE OR ALTER FUNCTION random_string(

@num INT,

@chars VARCHAR(1024) = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

) RETURNS VARCHAR(1024) AS

BEGIN

DECLARE @res_str VARCHAR(1024) = '';

DECLARE @i INT = 0;

WHILE (@i < @num)

BEGIN

SET @res_str = @res_str + SUBSTRING(@chars, FLOOR(dbo.rand_num(len(@chars))) + 1, 1);

SET @i = @i + 1;

END;

RETURN @res_str;

END;

```

使用示例:

```sql

-- 返回一个由字母和数字组成的长度为 10 的随机字符串

SELECT dbo.random_string(10, DEFAULT) AS rs;

-- 结果类似于:rs | -------------| 3CBFEPKYTd|

-- 返回一个长度为 6 的随机数字组成的手机验证码

SELECT dbo.random_string(6, '0123456789');

-- 结果类似于:random_string | -------------| 082661|

```

以下是重构后的代码:

```sql

-- 生成随机字符串

SELECT dbo.random_string(10 + rand() * 11, DEFAULT) AS rs;

rs | ---------------| 5ikNBTJLj1vKUKz|

-- 生成随机日期和时间

SELECT DATEADD(DAY, rand() * 15, CAST(GETDATE()AS date)) AS rand_date;

rand_date | ----------| 2020-12-18|

SELECT CAST(DATEADD(SECOND, rand() * 86400, GETDATE()) AS TIME) AS rand_time;

rand_time| ---------| 14:14:10|

-- 生成 UUID

SELECT NEWID() AS uuid;

uuid | ------------------------------------| 88E68504-7384-4AB8-A796-D13A8528AC21|

-- 如果想要生成没有中划线(-)的 UUID 字符串,可以使用 REPLACE 函数

SELECT REPLACE(NEWID(), '-', '') AS no_dash_uuid;

no_dash_uuid | ------------------------------| C4F5B9C9E6B94C5B9C9E6B9C9E6B9C9E|

```

以下是根据提供的内容重构后的内容:

SELECT REPLACE(NEWID(), '-', '') AS uuid;

uuid | 037C73E57F084E33AE026C949454AFF9|

在Microsoft SQL Server中获取表中的随机记录的方法有限。由于RAND函数每次返回相同的随机值,因此不能利用RAND函数从表中返回随机的数据行。但是可以使用NEWID函数。例如:

```sql

SELECT TOP(5) emp_id, emp_name FROM employee ORDER BY NEWID();

emp_id | emp_name | ------ |-------- |

18 | 法正 | | |

8 | 孙丫鬟 | | |

24 | 简雍 | | |

2 | 关羽 | | |

7 | 孙尚香 | | |

```

以上示例从employee表中返回了5个随机记录。该方法需要为表中的每行数据都生成一个随机数,然后进行排序;所以会随着表中的数据量增加而逐渐变慢。另外,Microsoft SQL Server中的查询语句支持TABLESAMPLE子句,可以实现数据的近似抽样,不过需要数据量大的时候才比较合适。