PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Seleziona una riga casuale da una tabella PostgreSQL con probabilità di riga ponderate

Questo dovrebbe fare il trucco:

WITH CTE AS (
    SELECT random() * (SELECT SUM(percent) FROM YOUR_TABLE) R
)
SELECT *
FROM (
    SELECT id, SUM(percent) OVER (ORDER BY id) S, R
    FROM YOUR_TABLE CROSS JOIN CTE
) Q
WHERE S >= R
ORDER BY id
LIMIT 1;

La sottoquery Q dà il seguente risultato:

1  50
2  85
3  100

Quindi generiamo semplicemente un numero casuale nell'intervallo [0, 100) e scegliamo la prima riga che è pari o superiore a quel numero (il WHERE clausola). Usiamo un'espressione di tabella comune (WITH ) per garantire che il numero casuale venga calcolato una sola volta.

BTW, il SELECT SUM(percent) FROM YOUR_TABLE ti consente di avere qualsiasi peso in percent - non devono necessariamente essere percentuali (cioè sommare fino a 100).

[SQL Fiddle]