2

在 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

不是我所期望的,所以我做错了什么?我希望生成一个伪随机序列。

4

2 回答 2

0

根据文档 RAND(n) 仅当 n 为常数时才能正常工作。使用非常量参数的效果是不确定的。从 MySQL 5.0.13 开始,不允许使用非常量参数。

正如他们所说,RAND() 并不是一个完美的随机生成器。这是一种按需生成随机数的快速方法,可在同一 MySQL 版本的平台之间移植。

MySQL 文档

检查如果您使用不带参数的 RAND() 会发生什么。

于 2014-11-28T12:03:55.667 回答
0

RAND() 并不意味着是一个完美的随机生成器,所以如果它不合适,那么应该使用其他生成随机数的方法。就我而言,我需要每天以不同的方式对行进行排序,RAND(CURDATE()+0)这被证明是一个可行的解决方案。

是的,似乎第一项的循环为 4,并且每次种子增加 4 时都会给它一个相似的随机数。

我从自己的随机数生成基本测试中得到以下结果,每次使用种子数 0、4、8 和 12 将种子增加 4。

  • 第 1 行:增加约 0.001
  • 第 2 行:增加约 0.005
  • 第 3 行:增加约 0.02
  • 第 4 行:增加约 0.05
  • 第 5 行:增加约 0.2
  • 第 6 行:减少了大约 0.01(或者可能增加了 0.99)
  • 第 7 行:增加约 0.26

在 OP 的示例中,因为它们不使用恒定的种子数,所以从技术上讲,它们的样本大小为 1。随着行数的增加,重复索引的影响会减小,并且其他项目出现在之前的可能性更高或在他们以前没有的其他项目之后。

我从使用中得出的一些警告RAND()

ifRAND()仅用作SELECT列或WHERE条件,并且LIMIT指定了 a,则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
于 2020-02-04T08:52:29.340 回答