В принципе, мне нужен рандомизатор, но вместо того, чтобы обрабатывать все строки одинаково (по 25% каждый), он должен обрабатывать его на основе процента, назначенного ему.
Например:
Event Chance_Percentage
A 25.00
B 10.00
C 15.00
D 50.00
Как я могу это достичь?
Я использую MySQL.
Более общее решение:
select e.*, t2.*
from (
select event,
(select coalesce(sum(chance_percentage), 0)
from table1 t2 where t2.event < t1.event) as lower_bound,
(select sum(chance_percentage)
from table1 t3 where t3.event <= t1.event) as upper_bound
from table1 t1) e
join (select 100.0 * rand() as p) t2
where t2.p >= e.lower_bound and t2.p < e.upper_bound;
Если вы просто хотите выбрать одно поле с вероятностью, равной проценту
Я думаю, что что-то вроде этого отлично работает: Set @mybound: = RAND() * 100; SELECT * FROM Event Где Chance_Percentage <@mybound ORDER BY Chance_Percentage desc limit 1
rand()
будет пересчитан для каждой строки. Вполне возможно, что это ничего не вернет.
Это довольно легко вычислить на языке программирования приложений, таком как Java, Python, C, php, JavaScript или что еще вы используете. Вы можете просто выбрать все свои строки в своем приложении и выполнить расчет там, где их легко написать.
Если в базе данных нет приложения NEED, то не делайте этого. Используйте правильный инструмент для правильной работы. База данных в первую очередь предназначена для сохранения, а не для вычислений.
См. Также проблему XY.
Сделайте кумулятивную сумму, а затем запустите rand()
один раз:
select t.event
from (select t.*, (@cume_p = @cume_p + p) as cume_p
from t cross join
(select @cume_p := 0, @rand = rand()) params
) t
where @rand >= cume_p - p and
@rand < cume_p;
Обратите внимание, что rand()
вызывается ровно один раз. Значение сохраняется в переменной; это произвольный выбор. Он также может быть в подзапросе:
select t.event
from (select t.*, (@cume_p = @cume_p + p) as cume_p
from t cross join
(select @cume_p := 0) params
) t cross join
(select rand() as r) r
where r.r >= cume_p - p and
r.r < cume_p;
У меня нет MySQL на моей машине, поэтому это не проверено, но я думаю, что эта общая идея будет работать.
SELECT Event
FROM Your_Table
WHERE CASE WHEN Event = 'A' THEN
CASE WHEN RAND() <= .25 THEN 1
END
WHEN Event = 'B' THEN
CASE WHEN RAND() <= .1 THEN 1
END
WHEN Event = 'C' THEN
CASE WHEN RAND() <= .15 THEN 1
END
WHEN Event = 'D' THEN
CASE WHEN RAND() <= .5 THEN 1
END
END = 1;