SQLite - ORDER BY RAND()

Ali*_*xel 64 mysql sql database sqlite random-access

在MySQL中我可以使用RAND()函数,在SQLite 3中有没有其他选择?

avn*_*nic 130

SELECT * FROM table ORDER BY RANDOM() LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

  • 并且对于记录,如果要随机排序整个表并以该随机顺序访问所有行,则限制不必为1. (3认同)
  • 如果您有一个复杂的 WHERE 子句并希望从该过滤列表中随机选择一行,这也将起作用。接受的答案并不容易支持。 (2认同)

dfa*_*dfa 49

使用random():

SELECT foo FROM bar
  WHERE id >= (abs(random()) % (SELECT max(id) FROM bar))
  LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

编辑(通过QOP):由于SQLite Autoincrement ed列上的文档声明:

只要您从不使用最大ROWID值,并且您永远不会删除具有最大ROWID的表中的条目,上述常规ROWID选择算法将生成单调递增的唯一 ROWID.如果您删除了行,则在创建新行时可能会重复使用先前删除的行中的ROWID.

如果你没有一个INTEGER PRIMARY KEY AUTOINCREMENT列(它仍然可以与INTEGER PRIMARY KEY列一起工作),上述情况才会成立.无论如何,这应该更便携/可靠:

SELECT foo FROM bar
  WHERE _ROWID_ >= (abs(random()) % (SELECT max(_ROWID_) FROM bar))
LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

ROWID,_ROWID_并且OID是SQLite内部行id的所有别名.

  • 是的,这个解决方案更快,但假设id从1开始并且没有间隙.否则,跟随间隙的行比其他行更频繁地"随机"选择. (14认同)
  • +1,这比id为index的其他选项更快. (2认同)
  • @Bill,谢谢你在我的回答中指出了问题 (2认同)
  • 哇,我的查询从> 300ms到1ms! (2认同)

Ali*_*xel 35

解决了:

SELECT * FROM table ORDER BY RANDOM() LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

  • 我不同意.我们现在有两位信息,如何随机选择一条记录,如何随机列出所有记录.我从来不需要做任何事,但如果我这样做,现在我知道如何做.我也知道MySQL与SQLlite不同.一个超级技术问题会更令人印象深刻,但不太有用. (8认同)
  • 我投了这票,因为他实际上先回答了. (4认同)

Ali*_*Ali 14

要获得更好的性能,请在SQLite中使用它:

SELECT * FROM table WHERE id IN (SELECT id FROM table ORDER BY RANDOM() LIMIT x) 
Run Code Online (Sandbox Code Playgroud)

这也适用于MySQL.这样运行得更快,因为SQL引擎首先将行的投影字段加载到内存然后对它们进行排序,这里我们只是加载并随机排序行的id字段,然后我们得到它们的X,并找到这些X ID的整行,默认索引.

  • +1。在我的环境中,这比“SELECT * FROM table ORDER BY RANDOM() LIMIT 1”快约 30 倍,并且仍然提供真正的随机,对表模式没有任何要求。 (3认同)