Вы хотите получить взвешенную выборку из случайной выборки. Для этой цели, вероятно, наиболее эффективным решением являются переменные:
select u.*
from (select u.*, (@t := @t + raffle_tickets) as running_tickets
from my_users u cross join
(select @t := 0, @r := rand()) params
where raffle_tickets > 0
) u
where @r >= (running_tickets - raffle_tickets) / @t and
@r < (running_tickets / @t);
Это вычисляет текущую сумму билетов, а затем делит ее на количество билетов, чтобы получить число от 0 до 1. Например, это может привести к:
my_id name raffle_tickets running_tickets running_tickets / @t
1 Bob 3 3 0.03571428571428571
2 Sam 59 62 0.7380952380952381
4 Jane 10 72 0.8571428571428571
5 Mike 12 84 1
Порядок исходных строк не имеет значения - вот почему в подзапросе нет упорядочения.
Затем соотношение используется с rand()
для выбора конкретной строки.
Обратите внимание, что во внешнем запросе @t
- это общее количество билетов.
Здесь - скрипт db <>.