Как выбрать N случайных строк, используя чистый SQL? - PullRequest
9 голосов
/ 29 декабря 2008

Как объединить Как запросить случайную строку в SQL? и Несколько случайных значений в SQL Server 2005 , чтобы выбрать N случайных строк с помощью одного запроса чистого SQL? В идеале, я бы хотел избежать использования хранимых процедур, если это возможно. Это вообще возможно?

ПОЯСНЕНИЯ

  1. Чистый SQL относится как можно ближе к стандарту ANSI / ISO.
  2. Решение должно быть "достаточно эффективным". Предоставленный ORDER BY RAND () может работать, но, как отмечали другие, это невозможно для таблиц среднего размера.

Ответы [ 5 ]

4 голосов
/ 29 декабря 2008

Ответ на ваш вопрос есть во второй ссылке:

SELECT * FROM table ORDER BY RAND() LIMIT 1

Просто измените лимит и / или переписайте для SQL Server:

SELECT TOP 1 * FROM table ORDER BY newid()

Теперь, это строго отвечает на ваш вопрос, но вы действительно не должны использовать это решение. Просто попробуйте на большом столе, и вы поймете, что я имею в виду.

Если ваше пространство клавиш является последовательным, либо без отверстий, либо с очень небольшим количеством отверстий, и если в нем очень мало отверстий, вы не слишком обеспокоены тем, что некоторые строки имеют немного более высокий шанс выбора, чем другие, тогда Вы можете использовать вариант, в котором вы вычисляете, какой ключ вы хотите получить случайным образом, в диапазоне от 1 до самого высокого ключа в вашей таблице, а затем извлекаете первую строку с ключом, равным или превышающим число, которое вы рассчитали. Часть «выше чем» нужна вам только в том случае, если в пространстве клавиш есть отверстия.

Этот SQL оставлен в качестве упражнения для читателя.


Редактировать : Обратите внимание, что в комментарии к другому ответу здесь упоминается, что, возможно, чистый SQL означает стандарт SQL ANSI. Если это так, то нет никакого способа, поскольку нет стандартизированной случайной функции, и при этом каждый механизм базы данных не обрабатывает функцию случайных чисел одинаково. По крайней мере один механизм, который я видел, «оптимизирует» вызов, вызывая его один раз и просто повторяя вычисленное значение для всех строк.

2 голосов
/ 20 марта 2013

Вот потенциальное решение, которое позволит вам сбалансировать риск получения менее чем N строк и смещения выборки из "передней части" таблицы. Это предполагает, что N мало по сравнению с размером таблицы:

select * from table where random() < (N / (select count(1) from table)) limit N;

Как правило, это будет выборка большей части таблицы, но она может вернуть меньше N строк. Если допустимо некоторое смещение, числитель может быть изменен с N на 1,5 * N или 2 * N, чтобы очень вероятно, что будет возвращено N строк. Кроме того, если необходимо рандомизировать порядок строк, а не просто выбрать случайное подмножество:

select * from (select * from table
                where random() < (N / (select count(1) from table)) limit N)
 order by mod(tableid,1111);

Недостатком этого решения является то, что, по крайней мере в PostgreSQL, он использует последовательное сканирование таблицы. Увеличенный числитель ускорит запрос.

2 голосов
/ 30 декабря 2008

Я не знаю о чистом ANSI, и это не просто, но вы можете проверить мой ответ на подобный вопрос здесь: Простые случайные выборки из базы данных Sql

0 голосов
/ 11 апреля 2014

Используя приведенный ниже код, вы можете добиться того же, что и вы ..

select top 1 * from student1 order by newid()

измените значение N, где топ 1, чтобы вы получили это количество случайных записей.

0 голосов
/ 17 апреля 2013

Это может вам помочь:

SELECT TOP 3 * FROM TABLE ORDER BY NEWID()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...