2016-03-24 71 views
0

我发现这完全令人震惊,但DB2中的rand()函数偶尔返回值为1。考虑对在它拥有大约150K行的表这个选择:DB2中的随机函数不是均匀分布的

在大多数语言/ DB的,等等,我预计这将返回10行数据,与分布为大致相等。我实际上得到的是列,如下列:

Num  N 
--- ----- 
10  12 
9  14871 
8  14975 
7  15213 
6  15004 
5  15196 
4  14998 
3  14916 
2  14926 
1  15081 
0  15017 

令人震惊!在我的用例中,我正在更新表中的行并希望分配一个随机值,但它需要随机分布,而不是上面的可怕情况。

所以我现在想我必须在一个循环中多次执行更新,在第二次...第n次迭代中继续尝试以不幸运行结束的行(以rand()结尾) = 1.0

或者,我可以使用rand()/ 1.00001,但这只是愚蠢的(也不是均匀分布的)!不知道如何更好地处理这个问题(没有,例如,写UDF的,等等,将不胜感激)。

+0

它是否返回0的确切值?如果没有,你可以通过四舍五入来做你想做的事。 –

+1

不知道为什么你会发现这个“令人震惊”或“惊人的”,因为你的桶不相等。考虑到0.9和0.999999之间的每个随机值进入“9”桶,但只有1.0正好进入“10”桶。 – mustaccio

回答

0

你会想到十行,但你得到11 - 和一个不喜欢预期的那么只是过滤它...

替代: 在伟大的SQL Cookbook有很多的周围随机数的信息。检查出来 - 也可以使用GENERATE_UNIQUE()

2

我就遇到了这个在2008年使用DB2/400 ...

兰特()返回一个范围[0,1]包容
兰特()* 10返回浮点的浮点值在范围值[0,10]包容

然后你转换为整数,你有什么是以下

[0.000, 0.9999] => 0 
[1.000, 1.9999] => 1 
[2.000, 2.9999] => 2 
[3.000, 3.9999] => 3 
[4.000, 4.9999] => 4 
[5.000, 5.9999] => 5 
[6.000, 6.9999] => 6 
[7.000, 7.9999] => 7 
[8.000, 8.9999] => 8 
[9.000, 9.9999] => 9 
[10.000, 10.000] => 10 

正如你所看到的,你就会有很多最终10比少任何其他号码。

乘法之后是截断问题。舍入而不是截断不起作用,因为仍然有一个范围较小的值导致0或10.

许多rand()函数返回范围[0,1)(不包括1)的值。但是DB2返回[0,1]。

我用DB2中的下列以获得0和N

floor(rand() * N + 0.99999) 

之间的随机整数,我认为分配仍可能有点过,从“完美”。但对我来说已经够好了。