2016-03-28 14 views
0

Ich benutze PostgreSQL-Datenbank und habe eine cards Tabelle.PostgreSQL nicht überlappende Bereiche

Jeder Datensatz (Karte) in dieser Tabelle hat Integer-Wert.

Zum Beispiel:

id | card_name |card_drop_rate 
------------------------------- 
1 |card1  |34 
2 |card2  |16 
3 |card3  |54 

max Drop-Rate ist 34 + 16 + 54 = 104.

Gemäß meiner Anwendungslogik muß ich einen zufälligen Wert zwischen 0 und 104 finden und dann Karte abrufen nach dieser Nummer, zum Beispiel:

Zufallswert: 71

card1 range: 0 - 34(0 + 34) 
card2 range: 34 - 50(34 + 16) 
card3 range: 50 - 104(50 + 54) 

So, meine Karte ist card3 weil 71 in den Bereich gesetzt wird 50 - 104

Was ist der richtige Weg, um diese Struktur in PostgreSQL widerzuspiegeln? Ich werde diese Daten oft unter abfragen müssen, so dass die Leistung ein Kriterium Nummer eins für diese Lösung ist.

Antwort

0

folgende Abfrage funktioniert gut:

SELECT 
b.id, 
b.card_drop_rate 
FROM (SELECT a.id, sum(a.card_drop_rate) OVER(ORDER BY id) - a.card_drop_rate as rate, card_drop_rate FROM cards as a) b 
WHERE b.rate < 299 ORDER BY id DESC LIMIT 1 
0

Sie können dies kumulative Summen und zufällig verwenden. Die „+ 1“ könnte mich weg werfen, aber es ist so etwas wie diese:

with c as (
     select c.*, 
      sum(card_drop_rate + 1) - card_drop_rate as threshhold 
     from cards c 
    ), 
    r as (
     select random() * (sum(card_drop_rate) + count(*) - 1) as which_card 
     from cards c 
    ) 
select c.* 
from c cross join 
    r 
where which_card >= threshhold 
order by threshhold 
limit 1; 

Für Leistung, würde ich einfach die Karten nehmen und eine neue Tabelle mit 106 Slots erzeugen. Weisen Sie den Slots den Kartenwert zu und erstellen Sie einen Index für die Slot-Nummer. Dann einen Wert erhalten mit:

select s.* 
from slots s 
where s.slotid = floor(random() * 107); 
+0

Danke für deine Antwort. Leider kann ich die erste Abfrage wegen eines Syntaxfehlers dort nicht ausführen. – alexanoid

+0

und ja, +1 kann da vermieden werden – alexanoid

Verwandte Themen