我使用的是MSSQL Server 2005。在我的db中,我有一个表“customerNames”,它有两列“Id”和“名称”和大约。1000年的结果。
我正在创建一个功能,每次都必须随机选择5个客户。谁能告诉我如何创建一个查询,将获得随机5行(Id,和名称)每次查询执行时?
我使用的是MSSQL Server 2005。在我的db中,我有一个表“customerNames”,它有两列“Id”和“名称”和大约。1000年的结果。
我正在创建一个功能,每次都必须随机选择5个客户。谁能告诉我如何创建一个查询,将获得随机5行(Id,和名称)每次查询执行时?
当前回答
这是一个老问题,但是尝试将一个新字段(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)
如果你想选择更多的行,我会考虑用一个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;
其他回答
如果有人想要PostgreSQL解决方案:
select id, name
from customer
order by random()
limit 5;
为了打乱SQL结果集,需要使用特定于数据库的函数调用。
请注意,使用RANDOM函数对大型结果集进行排序可能会非常慢,因此请确保对小型结果集进行排序。 如果你必须洗牌一个大的结果集,然后限制它,那么最好使用Oracle SAMPLE(N)或SQL Server或PostgreSQL中的TABLESAMPLE,而不是ORDER BY子句中的随机函数。
所以,假设我们有如下的数据库表:
以及歌曲表中的以下行:
| 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上,需要使用DBMS_RANDOM. conf文件。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 |
请注意,由于DBMS_RANDOM,这些歌曲是按随机顺序列出的。ORDER by子句使用的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子句使用了随机函数调用,歌曲是按随机顺序列出的。
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函数调用,歌曲是按随机顺序列出的。
也许这个网站会有帮助。
对于那些不想点击浏览的人:
SELECT TOP 1 column FROM table
ORDER BY NEWID()
SELECT TOP 5 Id, Name FROM customerNames
ORDER BY NEWID()
也就是说,每个人似乎都来这一页寻找你问题的更一般的答案:
在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
这是一个老问题,但是尝试将一个新字段(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)
如果你想选择更多的行,我会考虑用一个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;