Выберите случайную строку из MySQL (с вероятностью)

У меня есть таблица MySQL, которая ссорится названная cur_odds, который является числом процента с вероятностью процента, что та строка будет выбрана. Как я делаю запрос, который на самом деле выберет строки приблизительно в, что частота, когда Вы пробегаете 100 запросов, например?

Я попробовал следующее, но строка, которая имеет вероятность 0,35, заканчивает тем, что была выбрана приблизительно 60-70% времени.

SELECT * FROM table ORDER BY RAND()*cur_odds DESC

Все значения cur_odds в таблице составляют в целом 1 точно.

6
задан skaffman 8 July 2011 в 06:53
поделиться

2 ответа

Если cur_odds изменяется редко, вы можете реализовать следующий алгоритм:

1) Создайте еще один столбец prob_sum , для которого

prob_sum [0]: = cur_odds [0]

для 1 <= i <= row_count - 1:

prob_sum [i]: = prob_sum [i - 1] + cur_odds [i ]

2) Сгенерировать случайное число от 0 до 1:

rnd: = rand (0,1)

3) Найдите первую строку, для которой prob_sum> rnd (если вы создать индекс BTREE на prob_sum , запрос должен работать намного быстрее):

CREATE INDEX prob_sum_ind ON

(prob_sum);

SET @rnd: = RAND ();

ВЫБЕРИТЕ МИН (сумма_проблемы) ИЗ <таблица> ГДЕ_сумма_пробности> @rnd;

4
ответ дан 17 December 2019 в 00:06
поделиться

Учитывая приведенный выше оператор SQL, любые числа, которые у вас есть в cur_odds , являются не вероятностями выбора каждой строки, а просто произвольным взвешиванием (относительно "весов "всех остальных строк), что лучше всего можно было бы интерпретировать как относительную тенденцию плавать в верхней части отсортированной таблицы. Фактическое значение в каждой строке не имеет смысла (например, у вас может быть 4 строки со значениями 0,35, 0,5, 0,75 и 0,99, или у вас могут быть значения 35, 50, 75 и 99, и результаты будут такими же).

Обновление: Вот что происходит с вашим запросом. У вас есть одна строка со значением cur_odds 0,35. Для иллюстрации я предполагаю, что все остальные 9 строк имеют одинаковое значение (0,072). Также для иллюстрации предположим, что RAND () возвращает значение от 0,0 до 1,0 (на самом деле может).

Каждый раз, когда вы запускаете этот оператор SELECT, каждой строке присваивается значение сортировки путем умножения ее значения cur_odds на значение RAND () от 0,0 до 1,0. Это означает, что строка с 0,35 будет иметь значение сортировки от 0,0 до 0,35.

Каждая вторая строка (со значением 0,072) будет иметь значения сортировки в диапазоне от 0,0 до 0,072. Это означает, что существует примерно 80% вероятность того, что ваша одна строка будет иметь значение сортировки больше 0,072, что означает, что нет вероятности того, что любая другая строка может быть отсортирована выше. Вот почему ваша строка со значением cur_odds 0,35 появляется первой чаще, чем вы ожидаете.

Я неправильно описал значение cur_odds как относительное изменение веса. Фактически он функционирует как максимальное относительное взвешивание, которое затем потребует некоторой сложной математики для определения действительных относительных вероятностей.

Я не уверен, что то, что вам нужно, можно сделать с помощью обычного T-SQL. Я много раз реализовывал выборку взвешенной вероятности (по иронии судьбы сегодня утром собирался задать вопрос о лучших методах), но всегда в коде.

3
ответ дан 17 December 2019 в 00:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: