Как случайным образом выбрать строки в SQL? - PullRequest
187 голосов
/ 24 февраля 2009

Я использую MSSQL Server 2005. В моей базе данных есть таблица «customerNames», в которой есть два столбца «Id» и «Name» и ок. 1000 результатов.

Я создаю функциональность, в которой мне приходится каждый раз выбирать случайным образом 5 клиентов. Может кто-нибудь сказать мне, как создать запрос, который будет получать случайные 5 строк (Id и Name) каждый раз, когда запрос выполняется?

Ответы [ 9 ]

556 голосов
/ 31 июля 2009
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
34 голосов
/ 24 февраля 2009
SELECT TOP 5 Id, Name FROM customerNames ORDER BY NEWID()
8 голосов
/ 24 февраля 2009

В случае, если кто-то хочет решение PostgreSQL:

select id, name
from customer
order by random()
limit 5;
8 голосов
/ 24 февраля 2009

Может быть этот сайт будет полезен.

Для тех, кто не хочет нажимать:

SELECT TOP 1 column FROM table
ORDER BY NEWID()
6 голосов
/ 23 сентября 2012

Здесь есть отличное решение для Microsoft SQL Server 2005. Решает проблему, когда вы работаете с большим набором результатов (не тот вопрос, который я знаю).

Выбор строк случайным образом из большой таблицы http://msdn.microsoft.com/en-us/library/cc441928.aspx

4 голосов
/ 17 июля 2018

Это старый вопрос, но попытка применить новое поле (либо NEWID (), либо ORDER BY rand ()) к таблице с большим количеством строк была бы чрезмерно дорогой. Если у вас есть инкрементные уникальные идентификаторы (и у вас нет дыр), будет более эффективно вычислить 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)

Если вы хотите выбрать еще много строк, я бы посмотрел на заполнение #tempTable идентификатором и набором значений rand (), а затем использовал бы каждое значение rand () для масштабирования до значений min-max. Таким образом, вам не нужно определять все параметры @ 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
4 голосов
/ 25 февраля 2015

ВЫБРАТЬ * ИЗ ЗАКАЗА ТАБЛИЦЫ ПО Случайному () ПРЕДЕЛ 5;

3 голосов
/ 04 марта 2018

Если у вас есть таблица с миллионами строк и вы заботитесь о производительности, это может быть лучшим ответом:

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

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

3 голосов
/ 16 августа 2013

Я считаю, что это лучше всего работает для больших данных.

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

TABLESAMPLE(n ROWS) or TABLESAMPLE(n PERCENT) является случайным, но необходимо добавить TOP n, чтобы получить правильный размер выборки.

Использование NEWID() очень медленно для больших таблиц.

...