MySQL中的随机行

时间:2011-11-11 14:40:57

标签: mysql sql postgresql random

我想在MySQL中获得随机行。这是我的方法:

SELECT * 
FROM users 
WHERE id = 
 (SELECT floor((max(id) - min(id) + 1) * rand()) + min(id)
  FROM users);

当id中存在间隙时,这可以返回空集。我很好。然而,

  1. 我没有差距,而且我仍然经常得到空集
  2. 更令人不安的是:我会偶尔得到两个或更多结果
  3. 这种奇怪行为的原因是什么?怎么样,我做对了吗?

    注意:

    • 桌子很大(10 ^ 6 ... 10 ^ 7);我不能使用基于随机排序的任何明显且已知的解决方案,甚至不能使用 count()
    • 我坚持使用MySQL,我不在乎它是如何在客户端ruby / PHP /无论如何完成的。
    • 我试图投射浮动类型,但它没有帮助。
    • 相应的PostgreSQL变体(随机而不是rand,以及一些类型转换)工作正常。

5 个答案:

答案 0 :(得分:2)

我怀疑这是因为正在为主查询中的USERS表中的每一行评估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

答案 1 :(得分:1)

试试这个 -

SELECT t.* FROM
  users t,
  (SELECT @id := (FLOOR((MAX(id) - MIN(id) + 1) * RAND()) + MIN(id)) FROM users) t2
WHERE
  t.id = @id;

答案 2 :(得分: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;

答案 3 :(得分:0)

SELECT * FROM users ORDER BY rand() limit 1;

将返回一个随机行。

答案 4 :(得分:0)

怎么样:

SELECT * 
FROM users 
WHERE id >= (SELECT floor((max(id) - min(id) - 1) * rand())  + min(id) from users)
LIMIT 1

或类似的?

相当多,它应该限制你一个结果,如果它达到一个差距(不知何故),那么它只需要下一个可用的结果。