2016-03-28 11 views
0

私はPostgreSQLデータベースを使用し、cardsテーブルを持っています。PostgreSQL非重複範囲

この表の各レコード(カード)は、card_drop_rateの整数値です。例えば

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

最大のドロップ率が34 + 16 + 54 = 104です。私のアプリケーション・ロジックによると

私は0と104の間のランダムな値を検索し、例えば、この数に応じてカードを取得する必要があります。

ランダムな値:71

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

、私のカードはcard3です71が範囲に入っています50 - 104

この構造をPostgreSQLに反映させる適切な方法は何ですか?このデータを頻繁に照会する必要があるので、パフォーマンスはこのソリューションの基準番号1です。

答えて

0

次のクエリは正常に動作します:

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

累積合計とランダムを使用してこれを行うことができます。 「+ 1」は、私をオフに投げるかもしれないが、それはこのようなものです:

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; 

はパフォーマンスのために、私は単純にカードを取るだろうし、106個のスロットに新しいテーブルを生成します。カードの値をスロットに割り当て、スロット番号にインデックスを作成します。次に、使用して値を取得する:

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

おかげで、あなたが答えるために。残念なことに、そこにいくつかの構文エラーがあるため、最初のクエリを実行することはできません。 – alexanoid

+0

とはい、+1はそこで回避できます – alexanoid

関連する問題