SQL Выберите случайную строку на основе процента - PullRequest
0 голосов
/ 31 мая 2018

В основном мне нужен рандомизатор, но вместо того, чтобы обрабатывать все строки одинаково (по 25% каждая), он должен обрабатывать их на основе назначенного ему процента.

Например:

Event Chance_Percentage
A          25.00
B          10.00
C          15.00
D          50.00

Как бы я этого достиг?

Я использую MySQL.

Ответы [ 5 ]

0 голосов
/ 01 июня 2018

Выполните накопительную сумму, а затем выполните 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;
0 голосов
/ 31 мая 2018

Если вы просто хотите выбрать одно поле с вероятностью, равной проценту

Я думаю, что-то вроде этого будет работать нормально: Set @mybound: = RAND () * 100;SELECT * FROM Событие, в котором Chance_Percentage <@mybound ORDER BY Chance_Percentage desc limit 1 </p>

0 голосов
/ 31 мая 2018

Это должно быть довольно легко вычислить в языке программирования приложений, таком как Java, Python, C, php, JavaScript или что вы еще используете.Вы можете просто выбрать все свои строки в приложении и выполнить вычисления там, где их легко написать.

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

См. Также проблему XY .

0 голосов
/ 31 мая 2018

Более общее решение:

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;
0 голосов
/ 31 мая 2018

У меня не установлен 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...