SQL Server 随机数生成器不是随机的

标签 sql random

有人可以解释为什么下面的代码不会产生从 1 到 10 的均匀分布的值:

declare @tbl table (id int, nm int)

;with src(id) as (
select 1 union all select id+1 from src where id+1 <= 100000
)
insert @tbl(id, nm)
select id, ROUND(((9) * RAND(cast(newid() as varbinary)) + 1), 0)
from src
option (maxrecursion 0)

select nm, count(9)qty
from @tbl
group by nm

示例输出:
nm  qty
1   5523
2   11079
3   11190
4   11016
5   11026
6   11239
7   11149
8   11054
9   11243
10  5481

请注意,1 和 10 的数量大约是其他数字的一半。

我已采用以下方法来修复此缺陷:
declare @tbl table (id int, nm int)

;with src(id) as (
select 1 union all select id+1 from src where id+1 <= 100000
)
insert @tbl(id, nm)
select id, (abs(checksum(newid()))%10)+1
from src
option (maxrecursion 0)

select nm, count(9)qty
from @tbl
group by nm

示例输出:
nm  qty
1   10053
2   10146
3   10123
4   9939
5   9804
6   9895
7   9887
8   9907
9   10193
10  10053

如您所见,数字 1 和 10 的代表相同。有谁知道为什么第一种方法失败?

基思

已解决(有点):我想出了为什么第一种方法会失败。使用圆形是罪魁祸首。如果值分别介于 0.5 和 1 或 9.5 和 10 之间,则生成的浮点值将仅映射到 1 或 10。其他值的范围是两倍。例如 2 的范围是 1.5 到 2.5。现在你如何解决第一种方法?或者我们只是避免它?第一种方法在许多网站上显示为使用 rand() 生成整数值的“The”方法。当我弄清楚时,我会发布一个修复程序。

干杯!

最佳答案

感谢仅四舍五入 [1.0, 1.5)将导致 1。但是 [1.5, 2.5)将导致 2。这是间隔长度的两倍。等等。

如果没有必要,请不要使用浮点数。你的第二种方法要好得多。 checksum(newid())技术是我认为的最佳实践。 (主观地说,令人失望的是我们不得不求助于此类技巧来生成随机整数。)

关于SQL Server 随机数生成器不是随机的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30904475/

相关文章:

sql - 连接 4 个表 SQL

sql - SQL Server 中是否有根据全文索引的包含函数中匹配单词的数量进行排序

c# - System.Drawing.Color 的 SQL 数据类型

java - 如何使用 onClick for android 从按钮生成随机类结果?

javascript - 如何使用 randomBytes() 在 node.js 中生成随机 6 位密码

mysql - 在 MySQL 中选择随机行与另一个表进行 JOIN

SQL:如果不能将to_number设置为null

php - 使用 php PDO 和 MySQL 返回行值

database - 关于哈希盐的综合信息

c++ - 无法使用种子生成高斯分布