U kunt dit doen door rand()
. te gebruiken en vervolgens een cumulatieve som gebruiken. Ervan uitgaande dat ze optellen tot 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;
Opmerkingen:
rand()
wordt één keer aangeroepen in een subquery om een variabele te initialiseren. Meerdere oproepen naarrand()
zijn niet wenselijk.- Er is een kleine kans dat het willekeurige getal precies op de grens tussen twee waarden ligt. De
limit 1
kiest willekeurig 1. - Dit kan efficiënter worden gemaakt door de subquery te stoppen wanneer
cumep > @r
. - De waarden hoeven niet in een bepaalde volgorde te staan.
- Dit kan worden aangepast om kansen te verwerken waarbij de som niet gelijk is aan 1, maar dat zou een andere vraag zijn.