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


当前回答

而不是使用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

其他回答

对于SQL Server 2005和2008,如果我们想要一个随机的个别行样本(来自Books Online):

SELECT * FROM Sales.SalesOrderDetail
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), SalesOrderID) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)

晚了,但通过谷歌到达这里,所以为了子孙后代,我将添加一个替代解决方案。

另一种方法是使用TOP两次,顺序交替。我不知道它是否是“纯SQL”,因为它在TOP中使用了一个变量,但它在SQL Server 2008中工作。这里有一个例子,如果我想要一个随机的单词,我使用字典单词表。

SELECT TOP 1
  word
FROM (
  SELECT TOP(@idx)
    word 
  FROM
    dbo.DictionaryAbridged WITH(NOLOCK)
  ORDER BY
    word DESC
) AS D
ORDER BY
  word ASC

当然,@idx是目标表上从1到COUNT(*)的随机生成的整数。如果您的列被索引,您也会从中受益。另一个优点是可以在函数中使用它,因为NEWID()是不允许的。

最后,在同一个表上,上述查询的执行时间大约是NEWID()类型查询的1/10。YYMV。

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

这将需要更少的计算时间

sql中的随机函数可能会有所帮助。此外,如果您想限制为一行,只需在最后添加它。

SELECT column FROM table
ORDER BY RAND()
LIMIT 1

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

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