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.