MySQL WHERE RAND()行为

时间:2017-11-27 03:16:41

标签: mysql

考虑下表foo

 a   b   v
 0   9   1
10  19   2
20  29   3
30  39   4
40  49   5
50  59   6
60  69   7
70  79   8
80  89   9
90 100  10

ab是特定值v的下边界和上边界。示例:

x = 79 => v = 8  

可以使用以下语句完成此操作:

SELECT `v`
FROM `foo`
WHERE  79 BETWEEN `a` AND `b`

哪个MySQL正确返回:

v
8

对于作为输入提供的0到100之间的每个数字,MySQL将正确返回1和10之间的一个数字。

问题

但是,如果用随机数生成器替换输入数字,则行为会有所不同:

SELECT `v`
FROM `foo`
WHERE ROUND(RAND()*100) BETWEEN `a` AND `b`

MySQL可能会返回从空结果集到3个数字的任何内容,而不是只返回一个数字!

问题1
这是RAND()语句的预期行为吗?这种看似奇怪的行为的原因是什么?

问题2
考虑到预期目的,声明是否正确?什么是正确的?如何纠正这种行为?

2 个答案:

答案 0 :(得分:2)

使用单个查询的ansi-sql友好解决方案看起来像

SELECT x.rnd, `v`
FROM yourTable y
INNER JOIN (SELECT RAND()*100 rnd) x
WHERE x.rnd BETWEEN y.`a` AND y.`b`;

它只生成一次随机值,然后用于连接查询。

演示:http://rextester.com/YOIW49684

查询和基表是从Tim Biegeleisen

借来的

答案 1 :(得分:1)

如果要将相同的随机值应用于查询的每一行,则一个选项是使用会话变量:

SET @rnd = RAND()*100;
SELECT v
FROM foo
WHERE ROUND(@rnd) BETWEEN a AND b;

Demo