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

时间:2015-06-18 00:07:08

标签: sql random

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

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

示例输出:

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

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

我已采用以下方法来修复此漏洞:

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

示例输出:

<div class="videoframe"> <span id="video"><iframe width="320" height="180" src="https://www.youtube.com/embed/P2LBebH1IBU?list=PLnVpR1DYS2MHt8Ormx_CETTIy3cfjtMEU" frameborder="0"></iframe> </span></div>

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

基思

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

干杯!

1 个答案:

答案 0 :(得分:3)

由于仅舍入[1.0, 1.5)将导致1.但[1.5, 2.5)将导致2.这是间隔长度的两倍。等等。

如果您不需要,请不要使用花车。你的第二种方法要好得多。 checksum(newid())技术是我认为最佳实践。 (从主观上看,令人失望的是我们不得不求助于这样的黑客来产生随机整数。)