我有一个模型Quote
,它有两个属性: quote 和 probability 。我想选择随机引用,但必须更频繁地选择概率较高的引号。例如,如果我们有
$q1->probability == 0.15
和
$q2->probability == 0.75
后者必须选择的可能性<5> 。以下命令进行随机引用选择:
$quote = Quote::orderByRaw('RAND()')->first();
但我需要选择有偏见,如上所述。怎么做到这一点?
答案 0 :(得分: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 ],
]
然后,您将在0
和7
之间生成一个数字,因为这是所有权重的总和。此时,您将获取每个项目并从随机数中减去它。一个例子看起来像这样。
$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();
}
}
这是未经测试的代码,但我打赌它正确运行。
如果你有一个高负载服务器或一个巨大的报价数据库,你可能想要在第一部分调用缓存。