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


当前回答

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

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

其他回答

select r.id, r.name from table AS r
INNER JOIN(select CEIL(RAND() * (select MAX(id) from table)) as id) as r1
ON r.id >= r1.id ORDER BY r.id ASC LIMIT 1

这将需要更少的计算时间

我还没看出来答案有什么不同。我有一个额外的约束条件,给定一个初始种子,每次都要选择相同的行集。

对于MS SQL:

最小的例子:

select top 10 percent *
from table_name
order by rand(checksum(*))

规范化执行时间:1.00

NewId()例子:

select top 10 percent *
from table_name
order by newid()

规范化执行时间:1.02

NewId()比rand(checksum(*))慢不了多少,所以您可能不希望对大型记录集使用它。

初始种子选择:

declare @seed int
set @seed = Year(getdate()) * month(getdate()) /* any other initial seed here */

select top 10 percent *
from table_name
order by rand(checksum(*) % seed) /* any other math function here */

如果给定一个种子,你需要选择相同的集合,这似乎是可行的。

在SQL Server中,您可以将TABLESAMPLE与NEWID()结合使用,以获得相当好的随机性,并且仍然具有速度。如果您真的只想要1行或少量的行,这尤其有用。

SELECT TOP 1 * FROM [table] 
TABLESAMPLE (500 ROWS) 
ORDER BY NEWID()

用于MySQL获取随机记录

 SELECT name
  FROM random AS r1 JOIN
       (SELECT (RAND() *
                     (SELECT MAX(id)
                        FROM random)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1

详情http://jan.kneschke.de/projects/mysql/order-by-rand/

火鸟:

Select FIRST 1 column from table ORDER BY RAND()