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


当前回答

要小心,因为TableSample实际上并不返回随机的行样本。它引导您的查询查看组成行的8KB页面的随机样本。然后,对这些页面中包含的数据执行查询。由于数据在这些页面上的分组方式(插入顺序等),这可能导致数据实际上不是随机样本。

参见:http://www.mssqltips.com/tip.asp?tip=1308

该表的MSDN页面包含了如何生成实际随机数据样本的示例。

http://msdn.microsoft.com/en-us/library/ms189108.aspx

其他回答

似乎列出的许多想法仍然使用排序

但是,如果使用临时表,则可以分配一个随机索引(就像许多解决方案所建议的那样),然后获取第一个大于0到1之间任意数字的索引。

例如(对于DB2):

WITH TEMP AS (
SELECT COMLUMN, RAND() AS IDX FROM TABLE)
SELECT COLUMN FROM TABLE WHERE IDX > .5
FETCH FIRST 1 ROW ONLY

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

另一种方法是使用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 FIRST 1 column from table ORDER BY RAND()

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

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

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

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