I had the same requirements and was trying to write a query for SQL Sever. My answer is base on @gordon-linoff's query of using cumulative sum for probabilities.
with rand AS (SELECT id, random=RAND() FROM Tiers)
, cumsum AS (SELECT id, cum_sum=SUM(probability) Over (Order By id) from Tiers)
Select TOP 1 t.id,
t.name,
t.probability
FROM Tiers t
inner join rand r on t.id = r.id
inner join cumsum c on t.id = c.id
WHERE c.cum_sum - r.random >= 0
ORDER BY c.cum_sum - r.random ASC
I have wrote a full summary to test this at https://github.com/AlahmadiQ8/cumulative-probability-sql
Here is a visual explanation of the cumulative sum probability
item |
probability |
cumulative |
A |
0.2 |
0.2 |
B |
0.3 |
0.5 |
C |
0.5 |
1 |
If random number x = 0.45
, then most we should return item B
because x
is 0.2 < x <= 0.5
.
x
|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
0.2 0.5 1
└──────────┘ └───────────────┘ └───────────────────────────┘
A B C
SELECT SUM(CHANCE) FROM table
? – Eduino