我发现这完全令人震惊,但DB2中的rand()函数偶尔会返回值1。考虑对表中包含大约150K行的表进行选择:
select integer(rand()*10) as Num, count(*) as N
from TabWithAbout150KRows
group by integer(rand()*10)
order by 1 desc;
在大多数语言/ DB等中,我希望这会返回10行数据,其分布大致相等。我实际得到的是 11 行,如下所示:
Num N
--- -----
10 12
9 14871
8 14975
7 15213
6 15004
5 15196
4 14998
3 14916
2 14926
1 15081
0 15017
令人震惊!在我的用例中,我正在更新表中的行,并希望分配一个随机值,但它需要随机分布,而不是上面的可怕情况。
所以我目前正在考虑我必须在循环中多次进行更新,继续第2次〜第n次迭代,再次尝试不幸的行,最终得到rand()= 1.0
或者,我可以使用rand()/ 1.00001,但这只是愚蠢的(也没有均匀分布)!
关于更好地解决这个问题的任何想法(例如,不用编写UDF等,将会受到赞赏)。
答案 0 :(得分:2)
我在2008年使用DB2 / 400 ...
遇到了这个问题rand()返回一个浮点值,其范围为[0,1] rand()* 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)
我认为发行可能仍然与“完美”有点差异。但这对我来说已经足够了。
答案 1 :(得分:1)
你想要并且期望十行,但你得到十一行 - 而且一个不像预期的那样只过滤它......
替代:
在伟大的SQL Cookbook中,有很多关于随机数的信息。检查一下 - 也可以使用GENERATE_UNIQUE()
。