SQLite-ORDER BY RAND()


Answers:


54

使用random():

SELECT foo FROM bar
  WHERE id >= (abs(random()) % (SELECT max(id) FROM bar))
  LIMIT 1;

编辑(通过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;

ROWID,_ROWID_并且OID都是SQLite内部行ID的别名。


2
+1,如果id为index,这比其他选项要快得多。
— Emil H

16
是的,该解决方案速度更快,但是假设id从1开始且没有间隔。否则,比其他行更频繁地“随机”选择跟随间隙的行。
— 比尔·卡温

1
最低的ID几乎也不会被选择。
— 幸运

2
哇,我的查询从> 300ms变成了1ms!
— Louis Waweru 2011年

很好的解决方案,只能随机生成1行,但不能超过1的限制:/确实,我在DDB中只进行了4个输入,限制为5 =>进行了一次测试,有时我得到3个结果,有时会有4个结果...我认为较大的DDB会有更好的随机性,但是对于较小的DDB则没有。
— LE GALLBenoît2014年

146
SELECT * FROM table ORDER BY RANDOM() LIMIT 1;

5
对于记录来说,如果要随机排序整个表并以该随机顺序访问所有行,则限制不必为1。
— lemontwist 2012年

2
如果您具有复杂的WHERE子句,并且希望从该过滤列表中随机选择一个行,这也将起作用。接受的答案不那么容易支持。
— Cory Trese 2013年

还有一个,结果中没有返回重复的行,这就是我需要的(y)
— Hitesh Chavda,2015年

我为什么使用它有此错误信息消息:1st ORDER BY术语与结果集中的任何列都不匹配
— sikisis

40

解决了:

SELECT * FROM table ORDER BY RANDOM() LIMIT 1;

8
我不同意。现在我们这里有两点信息,如何随机选择一条记录,如何随机列出所有记录。我从来不需要做任何事情,但是如果我这样做了,现在我知道了。我也知道MySQL与SQLlite不同。超级技术问题会给人留下深刻的印象,但没有多大用处。
— 克里斯·黄·利弗

我首先想到的是,没有任何函数可以对结果进行随机排序,或者如果有这样的功能/函数,那就更加晦涩了-例如,SQLite触发器就是这种情况。
— Alix Axel

20

为了获得更好的性能,请在SQLite中使用以下代码:

SELECT * FROM table WHERE id IN (SELECT id FROM table ORDER BY RANDOM() LIMIT x) 

这也适用于MySQL。这运行得更快,因为SQL引擎首先将行的投影字段加载到内存中,然后对其进行排序,在这里,我们只对行的id字段进行加载和随机排序,然后获取其中的X个,并找到这些X id的整个行,即默认索引。


1
+1。在我的环境中,这比快30倍左右SELECT * FROM table ORDER BY RANDOM() LIMIT 1,并且仍然对表模式没有任何要求,却能提供真正的随机性。
— Alex Che
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.