如何在SQL中随机选择行?

时间:2009-02-24 06:14:13

标签: sql database random

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

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

12 个答案:

答案 0 :(得分:555)

SELECT TOP 5 Id, Name FROM customerNames
ORDER BY NEWID()

那就是说,每个人似乎都来到这个页面,对你的问题做出更一般的回答:

Selecting a random row in SQL

使用MySQL选择一个随机行:

SELECT column FROM table
ORDER BY RAND()
LIMIT 1

使用PostgreSQL选择一个随机行:

SELECT column FROM table
ORDER BY RANDOM()
LIMIT 1

使用Microsoft SQL Server选择随机行:

SELECT TOP 1 column FROM table
ORDER BY NEWID()

使用IBM DB2

选择随机行
SELECT column, RAND() as IDX 
FROM table 
ORDER BY IDX FETCH FIRST 1 ROWS ONLY

使用Oracle选择随机记录:

SELECT column FROM
( SELECT column FROM table
ORDER BY dbms_random.value )
WHERE rownum = 1

选择带有sqlite的随机行:

SELECT column FROM table 
ORDER BY RANDOM() LIMIT 1

答案 1 :(得分:34)

SELECT TOP 5 Id, Name FROM customerNames ORDER BY NEWID()

答案 2 :(得分:8)

也许this site会有所帮助。

对于那些不想点击的人:

SELECT TOP 1 column FROM table
ORDER BY NEWID()

答案 3 :(得分:8)

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

select id, name
from customer
order by random()
limit 5;

答案 4 :(得分:6)

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

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

答案 5 :(得分:3)

我发现这对大数据最有效。

`SELECT TOP 1 Column_Name FROM dbo.Table TABLESAMPLE(1 PERCENT);`

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

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

答案 6 :(得分:3)

SELECT * FROM TABLENAME ORDER BY random()LIMIT 5;

答案 7 :(得分:3)

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

SELECT * FROM Table1
WHERE (ABS(CAST(
  (BINARY_CHECKSUM
  (keycol1, NEWID())) as int))
  % 100) < 10

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

答案 8 :(得分:3)

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

DECLARE @maxValue int = (select max(id) from [TABLE])
DECLARE @minValue int = (select min(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)

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

DECLARE @NumItems int = 100;

DECLARE @maxValue int = (select max(id) from [TABLE])
DECLARE @minValue int = (select min(id) from [TABLE])

with cte (n) as (select 1 union all select n+1 from cte where n < @NumItems)
select cast( ((@maxValue + 1) - @minValue) * rand(cast(newid() as varbinary(100))) + @minValue as int) as tp into #Nt
from 
cte
select * from  #Nt ntt
inner join [TABLE] i 
        on i.id = ntt.tp
drop table #Nt

答案 9 :(得分:0)

正如我在this article中所解释的那样,为了改组SQL结果集,您需要使用特定于数据库的函数调用。

  

请注意,使用RANDOM函数对大型结果集进行排序可能会非常缓慢,因此请确保对小型结果集执行此操作。

     

如果您必须随机整理一个较大的结果集,然后再对其进行限制,那么最好使用Oracle SAMPLE(N)SQL Server中的PostgreSQLTABLESAMPLE之类的东西在ORDER BY子句中的随机函数。

因此,假设我们具有以下数据库表:

enter image description here

以及song表中的以下行:

| id | artist                          | title                              |
|----|---------------------------------|------------------------------------|
| 1  | Miyagi & Эндшпиль ft. Рем Дигга | I Got Love                         |
| 2  | HAIM                            | Don't Save Me (Cyril Hahn Remix)   |
| 3  | 2Pac ft. DMX                    | Rise Of A Champion (GalilHD Remix) |
| 4  | Ed Sheeran & Passenger          | No Diggity (Kygo Remix)            |
| 5  | JP Cooper ft. Mali-Koa          | All This Love                      |

Oracle

在Oracle上,您需要使用DBMS_RANDOM.VALUE函数,如以下示例所示:

SELECT
    artist||' - '||title AS song
FROM song
ORDER BY DBMS_RANDOM.VALUE

在Oracle上运行上述SQL查询时,我们将获得以下结果集:

| song                                              |
|---------------------------------------------------|
| JP Cooper ft. Mali-Koa - All This Love            |
| 2Pac ft. DMX - Rise Of A Champion (GalilHD Remix) |
| HAIM - Don't Save Me (Cyril Hahn Remix)           |
| Ed Sheeran & Passenger - No Diggity (Kygo Remix)  |
| Miyagi & Эндшпиль ft. Рем Дигга - I Got Love      |
  

请注意,由于ORDER BY子句使用了DBMS_RANDOM.VALUE函数调用,因此歌曲以随机顺序列出。

SQL Server

在SQL Server上,您需要使用NEWID函数,如以下示例所示:

SELECT
    CONCAT(CONCAT(artist, ' - '), title) AS song
FROM song
ORDER BY NEWID()

在SQL Server上运行上述SQL查询时,我们将获得以下结果集:

| song                                              |
|---------------------------------------------------|
| Miyagi & Эндшпиль ft. Рем Дигга - I Got Love      |
| JP Cooper ft. Mali-Koa - All This Love            |
| HAIM - Don't Save Me (Cyril Hahn Remix)           |
| Ed Sheeran & Passenger - No Diggity (Kygo Remix)  |
| 2Pac ft. DMX - Rise Of A Champion (GalilHD Remix) |
  

请注意,由于ORDER BY子句使用了NEWID函数调用,因此歌曲以随机顺序列出。

PostgreSQL

在PostgreSQL上,您需要使用random函数,如以下示例所示:

SELECT
    artist||' - '||title AS song
FROM song
ORDER BY random()

在PostgreSQL上运行上述SQL查询时,我们将获得以下结果集:

| song                                              |
|---------------------------------------------------|
| 2Pac ft. DMX - Rise Of A Champion (GalilHD Remix) |
| JP Cooper ft. Mali-Koa - All This Love            |
| Ed Sheeran & Passenger - No Diggity (Kygo Remix)  |
| HAIM - Don't Save Me (Cyril Hahn Remix)           |
| Miyagi & Эндшпиль ft. Рем Дигга - I Got Love      |
  

请注意,由于ORDER BY子句使用了random函数调用,因此歌曲以随机顺序列出。

MySQL

在MySQL上,您需要使用RAND函数,如以下示例所示:

SELECT
  CONCAT(CONCAT(artist, ' - '), title) AS song
FROM song
ORDER BY RAND()

在MySQL上运行上述SQL查询时,我们将获得以下结果集:

| song                                              |
|---------------------------------------------------|
| HAIM - Don't Save Me (Cyril Hahn Remix)           |
| Ed Sheeran & Passenger - No Diggity (Kygo Remix)  |
| Miyagi & Эндшпиль ft. Рем Дигга - I Got Love      |
| 2Pac ft. DMX - Rise Of A Champion (GalilHD Remix) |
| JP Cooper ft. Mali-Koa - All This Love            |
  

请注意,由于ORDER BY子句使用了RAND函数调用,因此歌曲以随机顺序列出。

答案 10 :(得分:0)

如果您正在使用大表,并且想访问10%的数据,请运行以下命令:SELECT TOP 10 PERCENT * FROM Table1 ORDER BY NEWID();

答案 11 :(得分:0)

如果你使用 Yandex 数据库,那么你应该使用

select column from table order by random (TableRow()) limit 1;