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


当前回答

在MSSQL(在11.0.5569上测试)中使用

SELECT TOP 100 * FROM employee ORDER BY CRYPT_GEN_RANDOM(10)

明显快于

SELECT TOP 100 * FROM employee ORDER BY NEWID()

其他回答

我不知道这有多有效,但我以前用过:

SELECT TOP 1 * FROM MyTable ORDER BY newid()

因为guid是非常随机的,所以顺序意味着您得到的是随机行。

请参阅这篇文章:从数据库表中随机选择一行的SQL。它介绍了在MySQL, PostgreSQL, Microsoft SQL Server, IBM DB2和Oracle中执行此操作的方法(以下内容是从该链接复制的):

用MySQL随机选择一行:

SELECT column FROM table
ORDER BY RAND()
LIMIT 1

使用PostgreSQL随机选择一行:

SELECT column FROM table
ORDER BY RANDOM()
LIMIT 1

使用Microsoft SQL Server随机选择一行:

SELECT TOP 1 column FROM table
ORDER BY NEWID()

使用IBM DB2选择一个随机行

SELECT column, RAND() as IDX 
FROM table 
ORDER BY IDX FETCH FIRST 1 ROWS ONLY

使用Oracle随机选择一条记录:

SELECT column FROM
( SELECT column FROM table
ORDER BY dbms_random.value )
WHERE rownum = 1

您也可以尝试使用new id()函数。

只需编写一个查询并使用order by new id()函数。它是随机的。

像Jeremies这样的解决方案:

SELECT * FROM table ORDER BY RAND() LIMIT 1

工作,但是它们需要对所有表进行顺序扫描(因为需要计算与每一行相关联的随机值——这样才能确定最小的值),即使对于中等大小的表,这也是相当慢的。我的建议是使用某种索引数字列(许多表都将这些列作为主键),然后编写如下内容:

SELECT * FROM table WHERE num_value >= RAND() * 
    ( SELECT MAX (num_value ) FROM table ) 
ORDER BY num_value LIMIT 1

如果num_value被索引,那么无论表大小如何,它都在对数时间内工作。注意:这里假设num_value在0..MAX(num_value)范围内均匀分布。如果您的数据集严重偏离这个假设,您将得到倾斜的结果(一些行会比其他行出现得更频繁)。

火鸟:

Select FIRST 1 column from table ORDER BY RAND()