如何在纯SQL中请求随机行(或尽可能接近真正的随机)?


当前回答

Oracle有更好的解决方案,而不是使用dbms_random。值,而它需要完全扫描dbms_random来排序行。值,对于大表来说非常慢。

用这个代替:

SELECT *
FROM employee sample(1)
WHERE rownum=1

其他回答

我不得不同意CD-MaN:使用“ORDER BY RAND()”将很好地用于小表或当你只做几次SELECT时。

我还使用“num_value >= RAND() *…”技术,如果我真的想获得随机结果,我在表中有一个特殊的“随机”列,我大约每天更新一次。单个UPDATE运行将花费一些时间(特别是因为必须在该列上建立索引),但它比每次运行select时为每一行创建随机数快得多。

一个简单而有效的方法从http://akinas.com/pages/en/blog/mysql_random_row/

SET @i = (SELECT FLOOR(RAND() * COUNT(*)) FROM table); PREPARE get_stmt FROM 'SELECT * FROM table LIMIT ?, 1'; EXECUTE get_stmt USING @i;

而不是使用RAND(),因为它是不鼓励的,你可以简单地得到max ID (= max):

SELECT MAX(ID) FROM TABLE;

在1..Max (= My_Generated_Random)

My_Generated_Random = rand_in_your_programming_lang_function(1..Max);

然后运行SQL:

SELECT ID FROM TABLE WHERE ID >= My_Generated_Random ORDER BY ID LIMIT 1

注意,它将检查id等于或高于所选值的任何行。 也可以在表中寻找行,并获得一个等于或低于My_Generated_Random的ID,然后修改查询如下:

SELECT ID FROM TABLE WHERE ID <= My_Generated_Random ORDER BY ID DESC LIMIT 1
 SELECT * FROM table ORDER BY RAND() LIMIT 1

最好的方法是在新列中放入一个随机值,并使用如下代码(伪代码+ SQL):

randomNo = random()
execSql("SELECT TOP 1 * FROM MyTable WHERE MyTable.Randomness > $randomNo")

这是MediaWiki代码采用的解决方案。当然,对于较小的值会有一些偏差,但他们发现,在没有获取行的情况下,将随机值包装为0就足够了。

Newid()解决方案可能需要全表扫描,以便为每一行分配一个新的guid,这将大大降低性能。

rand()解决方案可能根本不起作用(即与MSSQL),因为函数将只计算一次,并且每一行将被分配相同的“随机”数字。