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


当前回答

火鸟:

Select FIRST 1 column from table ORDER BY RAND()

其他回答

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

但是,如果使用临时表,则可以分配一个随机索引(就像许多解决方案所建议的那样),然后获取第一个大于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

对于SQL Server 2005及以上版本,在num_value没有连续值的情况下扩展@GreyPanther的答案。这也适用于数据集分布不均匀以及num_value不是数字而是唯一标识符的情况。

WITH CTE_Table (SelRow, num_value) 
AS 
(
    SELECT ROW_NUMBER() OVER(ORDER BY ID) AS SelRow, num_value FROM table
) 

SELECT * FROM table Where num_value = ( 
    SELECT TOP 1 num_value FROM CTE_Table  WHERE SelRow >= RAND() * (SELECT MAX(SelRow) FROM CTE_Table)
)

如果可能的话,使用存储语句来避免RND()上的索引和创建记录编号字段的效率低下。

PREPARE RandomRecord FROM "SELECT * FROM table LIMIT ?,1";
SET @n=FLOOR(RAND()*(SELECT COUNT(*) FROM table));
EXECUTE RandomRecord USING @n;

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

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

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

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

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