Você pode fazer isso usando
rand()
e, em seguida, usando uma soma cumulativa. Supondo que eles somam 100%:select t.*
from (select t.*, (@cumep := @cumep + chance) as cumep
from t cross join
(select @cumep := 0, @r := rand()) params
) t
where @r between cumep - chance and cumep
limit 1;
Notas:
rand()
é chamado uma vez em uma subconsulta para inicializar uma variável. Várias chamadas pararand()
não são desejáveis.- Há uma chance remota de que o número aleatório esteja exatamente no limite entre dois valores. O
limit 1
escolhe arbitrariamente 1. - Isso pode ser mais eficiente parando a subconsulta quando
cumep > @r
. - Os valores não precisam estar em nenhuma ordem específica.
- Isso pode ser modificado para lidar com chances em que a soma não é igual a 1, mas isso seria outra pergunta.