MySQL中的随机行
我试图在MySQL中获得一个随机行。我的做法如下:MySQL中的随机行,mysql,sql,postgresql,random,Mysql,Sql,Postgresql,Random,我试图在MySQL中获得一个随机行。我的做法如下: SELECT * FROM users WHERE id = (SELECT floor((max(id) - min(id) + 1) * rand()) + min(id) FROM users); 当ID中存在间隙时,这可能返回一个空集。我同意。但是, 我没有空白,而且我仍然经常得到一个空集 更令人不安的是:我每隔一段时间就会得到两个或更多的结果 这种奇怪行为的原因是什么?我怎么做才对呢 注: 桌子很大(10^6…10^7
SELECT *
FROM users
WHERE id =
(SELECT floor((max(id) - min(id) + 1) * rand()) + min(id)
FROM users);
当ID中存在间隙时,这可能返回一个空集。我同意。但是,
- 桌子很大(10^6…10^7);我不能使用任何明显的、已知的基于随机排序的解决方案,甚至不能使用count()
- 我一直在使用MySQL,我不在乎它在客户端ruby/PHP/什么的上是如何实现的
- 我试图铸造浮动类型,但没有帮助李>
- 相应的PostgreSQL变体(random而不是rand,以及一些类型转换)工作正常
SELECT *
FROM users
WHERE id >= (SELECT floor((max(id) - min(id) - 1) * rand()) + min(id) from users)
LIMIT 1
还是类似的
基本上,它应该将您限制为一个结果,如果它(以某种方式)遇到了一个差距,那么它将只接受下一个可用的结果。试试这一个-
SELECT t.* FROM
users t,
(SELECT @id := (FLOOR((MAX(id) - MIN(id) + 1) * RAND()) + MIN(id)) FROM users) t2
WHERE
t.id = @id;
我怀疑这是因为对主查询中用户表中的每一行都计算了
RAND()
。我建议:
SELECT u1.*
from users u1,
(SELECT floor((max(id) - min(id) + 1) * rand()) + min(id) lid from users) u2
WHERE u1.id > u2.lid
LIMIT 1
这避免了聚合过程中重复计算
random()
,而且应该更快,因为min(id)
和random()
只计算一次
SELECT u.*
FROM users u
,(SELECT min(id) AS min_id, max(id) AS max_id FROM users) x
WHERE u.id > (floor((x.max_id - x.min_id + 1) * rand()) + x.min_id)
LIMIT 1;
OP确实解释了他们的表非常大,这使得这个查询非常慢。关于如何从表中(快速)获得一个随机行,请参见Karwin的回答:你也可以通过@Quassnoi阅读这篇文章:你能在mysql提示符下重现这些结果吗?在这些情况下,最小(id)、最大(id)和选择的id是什么?你能把你的数据集缩减到一个更小的尺寸并重现行为吗?
SELECT u.*
FROM users u
,(SELECT min(id) AS min_id, max(id) AS max_id FROM users) x
WHERE u.id > (floor((x.max_id - x.min_id + 1) * rand()) + x.min_id)
LIMIT 1;