Как случайным образом выбирать строки в SQL?

Я использую MSSQL Server 2005. В моем db у меня есть таблица "customerNames", которая имеет два столбца: "Id" и "Name" и ок. 1000 результатов.

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

Ответ 1

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

Ответ 2

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

Ответ 3

Возможно, этот сайт будет полезен.

Для тех, кто не хочет переходить по ссылке:

SELECT TOP 1 column FROM table
ORDER BY NEWID()

Ответ 4

Если кто-то хочет решение PostgreSQL:

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

Ответ 5

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

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

Ответ 6

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

Ответ 7

Это старый вопрос, но попытка применить новое поле (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() для масштабирования до минимальных и максимальных значений. Таким образом, вам не нужно определять все параметры @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

Ответ 8

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

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

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

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

Ответ 9

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

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

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

Ответ 10

Как я объяснил в этой статье, чтобы перетасовать набор результатов SQL, вам нужно использовать вызов функции для конкретной базы данных.

Обратите внимание, что сортировка большого результирующего набора с использованием функции RANDOM может оказаться очень медленной, поэтому убедитесь, что вы делаете это на маленьких результирующих наборах.

Если вам нужно перетасовать большой набор результатов и ограничить его впоследствии, то лучше использовать что-то вроде Oracle SAMPLE(N) или TABLESAMPLE в SQL Server или PostgreSQL вместо случайной функции в предложении 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 вам нужно использовать функцию DBMS_RANDOM.VALUE, как показано в следующем примере:

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

При выполнении вышеупомянутого SQL-запроса в Oracle мы получим следующий набор результатов:

| 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.VALUE используется предложением ORDER BY.

SQL Server

В SQL Server вам необходимо использовать функцию NEWID, как показано в следующем примере:

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

При выполнении вышеупомянутого SQL-запроса на SQL Server мы получим следующий набор результатов:

| 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) |

Обратите внимание, что песни перечислены в случайном порядке благодаря NEWID функции NEWID используется предложением ORDER BY.

PostgreSQL

В PostgreSQL вам нужно использовать функцию random, как показано в следующем примере:

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

При выполнении вышеупомянутого SQL-запроса на PostgreSQL мы получим следующий набор результатов:

| 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      |

Обратите внимание, что песни перечислены в случайном порядке благодаря random вызову функции, используемому предложением ORDER BY.

MySQL

В MySQL вам нужно использовать функцию RAND, как показано в следующем примере:

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

При выполнении вышеупомянутого SQL-запроса на MySQL, мы собираемся получить следующий набор результатов:

| 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            |

Обратите внимание, что песни перечислены в случайном порядке благодаря вызову функции RAND используется предложением ORDER BY.