如何在SQL中随机选择行?

Pra*_*ant 203 sql database random

我正在使用MSSQL Server 2005.在我的数据库中,我有一个表"customerNames",它有两列"Id"和"Name"和大约.1,000个结果.

我正在创建一个功能,每次我必须随机挑选5个客户.任何人都可以告诉我如何创建一个查询,每次执行查询时将获得随机的5行(Id和Name)?

Cur*_*ker 593

SELECT TOP 5 Id, Name FROM customerNames
ORDER BY NEWID()
Run Code Online (Sandbox Code Playgroud)

也就是说,每个人似乎都来到这个页面,以获得更一般的答案:

在SQL中选择一个随机行

用MySQL选择一个随机行:

SELECT column FROM table
ORDER BY RAND()
LIMIT 1
Run Code Online (Sandbox Code Playgroud)

使用PostgreSQL选择一个随机行:

SELECT column FROM table
ORDER BY RANDOM()
LIMIT 1
Run Code Online (Sandbox Code Playgroud)

使用Microsoft SQL Server选择随机行:

SELECT TOP 1 column FROM table
ORDER BY NEWID()
Run Code Online (Sandbox Code Playgroud)

使用IBM DB2选择随机行

SELECT column, RAND() as IDX 
FROM table 
ORDER BY IDX FETCH FIRST 1 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

使用Oracle选择随机记录:

SELECT column FROM
( SELECT column FROM table
ORDER BY dbms_random.value )
WHERE rownum = 1
Run Code Online (Sandbox Code Playgroud)

选择带有sqlite的随机行:

SELECT column FROM table 
ORDER BY RANDOM() LIMIT 1
Run Code Online (Sandbox Code Playgroud)

  • 这在大型表上是否变得非常昂贵,其中每一行都有一个随机数,然后一个大的无索引的随机数集被排序? (16认同)
  • +1感谢除OP的MSSQL之外添加其他数据库. (15认同)
  • 警告:对于大型数据库,此方法的性能会很差.你能想象如果数据库有一百万个条目,那么为每一行生成随机值所需的时间是多少?您可以获得更多信息和更好的替代方案[这里](https://www.warpconduit.net/2011/03/23/selecting-a-random-record-using-mysql-benchmark-results/). (4认同)
  • +1用于直接在SO上发布答案,而不是链接到外部网站(如接受的答案),当未来的用户查看此问题时可能会失败. (3认同)

Cod*_*lan 34

SELECT TOP 5 Id, Name FROM customerNames ORDER BY NEWID()
Run Code Online (Sandbox Code Playgroud)


小智 8

也许这个网站会有所帮助.

对于那些不想点击的人:

SELECT TOP 1 column FROM table
ORDER BY NEWID()
Run Code Online (Sandbox Code Playgroud)

  • 应该至少用5替换1 :) (2认同)

Bar*_*own 8

如果有人想要PostgreSQL解决方案:

select id, name
from customer
order by random()
limit 5;
Run Code Online (Sandbox Code Playgroud)


Joh*_*hnC 6

这里有一个很好的Microsoft SQL Server 2005特定解决方案.处理使用大型结果集的问题(不是我知道的问题).

从大表中随机选择行 http://msdn.microsoft.com/en-us/library/cc441928.aspx


小智 6

我发现这最适合大数据。

SELECT TOP 1 Column_Name FROM dbo.Table TABLESAMPLE(1 PERCENT);
Run Code Online (Sandbox Code Playgroud)

TABLESAMPLE(n ROWS) or TABLESAMPLE(n PERCENT)是随机的,但需要添加TOP n以获得正确的样本量。

NEWID()在大表上使用非常慢。


Toh*_*hid 6

如果您有一个包含数百万行的表并关心性能,这可能是一个更好的答案:

SELECT * FROM Table1
WHERE (ABS(CAST(
  (BINARY_CHECKSUM
  (keycol1, NEWID())) as int))
  % 100) < 10
Run Code Online (Sandbox Code Playgroud)

https://msdn.microsoft.com/en-us/library/cc441928.aspx


RIa*_*lis 6

这是一个老问题,但尝试将新字段(NEWID() 或 ORDER BY rand())应用于具有大量行的表将非常昂贵。如果您有增量的、唯一的 ID(并且没有任何漏洞),计算要选择的 ID 的 X # 而不是将 GUID 或类似的应用到每一行然后取顶部的 X # 会更有效。

DECLARE @minValue int;
DECLARE @maxValue int;
SELECT @minValue = min(id), @maxValue = max(id) from [TABLE];

DECLARE @randomId1 int, @randomId2 int, @randomId3 int, @randomId4 int, @randomId5 int
SET @randomId1 = ((@maxValue + 1) - @minValue) * Rand() + @minValue
SET @randomId2 = ((@maxValue + 1) - @minValue) * Rand() + @minValue
SET @randomId3 = ((@maxValue + 1) - @minValue) * Rand() + @minValue
SET @randomId4 = ((@maxValue + 1) - @minValue) * Rand() + @minValue
SET @randomId5 = ((@maxValue + 1) - @minValue) * Rand() + @minValue

--select @maxValue as MaxValue, @minValue as MinValue
--  , @randomId1 as SelectedId1
--  , @randomId2 as SelectedId2
--  , @randomId3 as SelectedId3
--  , @randomId4 as SelectedId4
--  , @randomId5 as SelectedId5

select * from [TABLE] el
where el.id in (@randomId1, @randomId2, @randomId3, @randomId4, @randomId5)
Run Code Online (Sandbox Code Playgroud)

如果您想选择更多行,我会考虑使用 ID 和一堆 rand() 值填充 #tempTable,然后使用每个 rand() 值缩放到最小-最大值。这样您就不必定义所有 @randomId1...n 参数。我在下面包含了一个使用 CTE 填充初始表的示例。

DECLARE @NumItems int = 100;

DECLARE @minValue int;
DECLARE @maxValue int;
SELECT @minValue = min(id), @maxValue = max(id) from [TABLE];
DECLARE @range int = @maxValue+1 - @minValue;

with cte (n) as (
   select 1 union all
   select n+1 from cte
   where n < @NumItems
)
select cast( @range * rand(cast(newid() as varbinary(100))) + @minValue as int) tp
into #Nt
from cte;

select * from #Nt ntt
inner join [TABLE] i on i.id = ntt.tp;

drop table #Nt;
Run Code Online (Sandbox Code Playgroud)


Nar*_*dra 5

SELECT * FROM TABLENAME ORDER BY random() LIMIT 5; 
Run Code Online (Sandbox Code Playgroud)