Задача
Вы хотите выбрать случайным образом элемент или элементы из набора значений.
Решение
Рандомизируйте значения, затем выберите первое из них (или несколько первых).
Обсуждение
Если набор значений хранится в MySQL, то вы можете произвольно извлечь одно из них так:
• Выбираем элементы в произвольном порядке при помощи ORDER BY RAND().
• Добавляем в запрос LIMIT 1 для извлечения первого элемента.
Например, простой симулятор бросания костей можно реализовать путем создания таблицы die, строки которой содержат значения от 1 до 6, соответствующие шести граням кубика, и случайного выбора строк из нее:
mysql> SELECT n FROM die ORDER BY RAND() LIMIT 1;
+--+
| n |
+--+
| 6 |
+--+
mysql> SELECT n FROM die ORDER BY RAND() LIMIT 1;
+--+
| n |
+--+
| 4 |
+--+
mysql> SELECT n FROM die ORDER BY RAND() LIMIT 1;
+--+
| n |
+--+
| 5 |
+--+
mysql> SELECT n FROM die ORDER BY RAND() LIMIT 1;
+--+
| n |
+--+
| 4 |
+--+
По мере повторения операции вы выбираете случайную последовательность элементов множества. Это выбор с возвращением: элемент выбирается из со-вокупности элементов, а затем возвращается в нее для следующей выборки.
Так как элементы возвращаются на место, есть шанс выбрать один и тот же элемент несколько раз последовательно. Можно привести и другие примеры выбора с возвращением:
• Выбор баннера для показа на веб-странице.
• Выбор строки для «цитаты дня».
• Фокусы типа «Выберите карту, любую карту», каждый раз начинающиеся с полной колоды.
Если вы хотите выбрать не один, а несколько элементов, то измените аргумент LIMIT. Например, чтобы произвольным образом извлечь пять выигрышных строк из таблицы drawing, содержащей конкурсные записи, используйте RAND() в сочетании с LIMIT:
SELECT * FROM drawing ORDER BY RAND() LIMIT 5;
Особым случаем является извлечение одной строки из таблицы, про которую известно, что она содержит столбец со значениями в диапазоне от 1 до n в непрерывной последовательности. В данной ситуации можно избежать выполнения операции ORDER BY для всей таблицы, выбирая случайное число в данном диапазоне и выбирая соответствующую строку:
SET @id = FLOOR(RAND()*n)+1;
SELECT ... FROM имя_таблицы WHERE id = @id;
При увеличении размера таблицы второй вариант работает гораздо быстрее, чем ORDER BY RAND() LIMIT 1.