2016-05-01 222 views
1

我有一個模型Quote,它有兩個屬性:報價概率。我想選擇一個隨機報價,但必須更頻繁地選擇具有較高概率的報價。例如,如果我們有雄辯 - 隨機選擇一個記錄

$q1->probability == 0.15 

$q2->probability == 0.75 

後者必須5倍,可能被選擇。下面的命令使隨機報價選擇:

$quote = Quote::orderByRaw('RAND()')->first(); 

但我需要選擇要,因爲它是上面提到的。如何實現這一目標?

回答

3

我不知道是否有辦法只有做到這一點與MySQL,但這個問題已經被提出之前用PHP解決:Generating random results by weight in PHP?

從本質上講,你想拉報價ID和重量([ id => 1, weight => 0.5] )和所有權重的總和(在你的例子中爲0.90)。然後,按照沒有特定的順序,遍歷數組並減去每個權重。

所以,如果我有這些值的MySQL表,

[ 
    [ 'id' => 1, weight => 1 ], 
    [ 'id' => 2, weight => 2 ], 
    [ 'id' => 3, weight => 4 ], 
] 

你會再生成07之間的數字,因爲這是所有的權重的總和。此時,您將每個項目從隨機數中減去。一個例子看起來像這樣。

$quoteWeights = Quote::select('id', 'weight')->get(); 
$weightSum = $quoteWeights->sum('weight'); 
$weightRand = mt_rand(0, $weightSum); 

foreach ($quoteWeights as $quoteWeight) 
{ 
    // Subtract our weight from the rand. 
    $weightRand -= $quoteWeight->weight; 

    // If it's bust, we want to return the winning model. 
    if ($weightRand <= 0) 
    { 
     // Refresh the model so we get all attributes. 
     return $quoteWeight->fresh(); 
    } 
} 

這是未經測試的代碼,但我打賭它正常運行。

如果您有一個高負載服務器或一個巨大的報價數據庫,您可能需要在第一部分調用緩存。

+0

感謝您的回答。好的技術 –