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

我试图在MySQL中获得一个随机行。我的做法如下:

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;