在Windows 7上使用MySQL 5.6.21。
我试图从日期播种的表中返回一个“随机”行(所以同一行返回当天,然后切换第二天等 - 如果你喜欢,则是“日期生成器的随机引用” )。
我注意到相同的行不断出现所以我将查询简化为基础,看起来RAND()函数每四个种子值生成非常相似的数字。舍入为整数时,值似乎每四个种子重复一次。这个例子只使用16行,但你明白了。
create table t (i INT);
insert into t values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15);
select i, ceil(rand(i) * 16), rand(i) from t;
drop table t;
...给出
0 3 0.15522042769493574
1 7 0.40540353712197724
2 11 0.6555866465490187
3 15 0.9057697559760601
4 3 0.15595286540310166
5 7 0.40613597483014313
6 11 0.6563190842571847
7 15 0.9065021936842261
8 3 0.15668530311126755
9 7 0.406868412538309
10 11 0.6570515219653505
11 15 0.907234631392392
12 3 0.15741774081943347
13 7 0.40760085024647497
14 11 0.6577839596735164
15 15 0.9079670691005579
不是我的预期,所以我做错了什么?我期望生成一个伪随机序列。
答案 0 :(得分:0)
RAND()并不是完美的随机生成器,因此,如果不合适,则应使用其他生成随机数的方式。就我而言,我需要每天对行进行不同的排序,事实证明RAND(CURDATE()+0)
是一个可行的解决方案。
是的,似乎第一项的周期为4,并且每当种子增加4时,它就会被赋予相似的随机数。
我自己进行的随机数生成基础测试得到了以下结果,并使用种子数0、4、8和12每次将种子加4。
在OP的示例中,由于它们不使用恒定的种子数,因此从技术上讲,它们的样本大小为1。随着行数的增加,对重复索引的影响会减小,并且其他项目将更有可能在其他项目之前或之后出现在其他项目之前或之后。
我使用RAND()
得出的一些警告:
如果仅将RAND()
用作SELECT
列或WHERE
条件,并且指定了LIMIT
,则RAND()
只会为每个返回的行。
CREATE TABLE t (i INT);
INSERT INTO t VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15);
SELECT i, RAND(0) FROM t LIMIT 0, 1; # 0, 0.15522042769493574
SELECT i, RAND(0) FROM t LIMIT 1, 1; # 1, 0.15522042769493574
如果在RAND()
语句中使用了ORDER BY
,那么将为所有匹配的行计算RAND()
,而不考虑任何LIMIT
。
CREATE TABLE t (i INT);
INSERT INTO t VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15);
SELECT i, RAND(0) FROM t ORDER BY RAND(0) LIMIT 0, 1; # 0, 0.15522042769493574
SELECT i, RAND(0) FROM t ORDER BY RAND(0) LIMIT 1, 1; # 6, 0.2964166321758336
答案 1 :(得分:-1)
根据文件,只有当n是常数时,RAND(n)才能正常工作。 使用非常量参数的效果未定义。从MySQL 5.0.13开始,不允许使用非常量参数。
正如他们所说 RAND()并不是一个完美的随机发生器。这是一种快速生成按需随机数的方法,可以在同一MySQL版本的平台之间移植。
检查在没有参数的情况下使用RAND()会发生什么。