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


当前回答

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

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

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

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

其他回答

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

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

耗时7.4毫秒

WHERE num_value >= RAND() * (SELECT MAX(num_value) FROM table)

只需要0.0065毫秒!

我肯定会选择后一种方法。

火鸟:

Select FIRST 1 column from table ORDER BY RAND()

正如@BillKarwin对@cnu回答的评论所指出的那样…

当与LIMIT结合使用时,我发现随机排序的JOIN比直接对实际行进行排序执行得更好(至少在PostgreSQL 9.1中)。 SELECT * FROM tbl_post AS t 加入…… JOIN (SELECT id, CAST(-2147483648 * RANDOM() AS integer) AS rand 从tbl_post WHERE create_time >= 1349928000 ) r ON r.id = t.d id WHERE create_time >= 1349928000 AND… ORDER BY r.r rand 限制100

只要确保“r”为与它连接的复杂查询中的每个可能的键值生成一个“rand”值,但仍然尽可能限制“r”的行数。

CAST as Integer对于PostgreSQL 9.2特别有用,它对整型和单精度浮点类型有特定的排序优化。