从MySQL中选择随机行(概率)

时间:2010-04-26 19:14:57

标签: mysql probability

我有一个MySQL表,其中有一行名为cur_odds,这是一个百分数,该行的概率百分比将被选中。例如,当您运行100个查询时,如何进行实际选择大约该频率的行的查询?

我尝试了以下操作,但是有一个概率为0.35的行最终会在60-70%的时间内被选中。

SELECT * FROM table ORDER BY RAND()*cur_odds DESC

表格中cur_odds的所有值恰好合计为1。

2 个答案:

答案 0 :(得分:4)

如果很少更改cur_odds,您可以实施以下算法:

1)创建另一列prob_sum,其中

  

prob_sum [0]:= cur_odds [0]

     

for 1< = i< = row_count - 1:

     

prob_sum [i]:= prob_sum [i - 1] + cur_odds [i]

2)生成0到1之间的随机数:

  

rnd:= rand(0,1)

3)查找prob_sum > rnd的第一行(如果在prob_sum上创建BTREE索引,则查询应该更快地运行):

  

CREATE INDEX prob_sum_ind ON< table> (prob_sum);

     

SET @rnd:= RAND();

     

SELECT MIN(prob_sum)FROM< table>在哪里prob_sum> @rnd;

答案 1 :(得分:3)

鉴于您的上述SQL语句,cur_odds中的数字选择每行的概率,而只是一个任意加权(相对于“权重”)其中所有其他行可能最好被解释为向排序表顶部浮动的相对趋势。每行中的实际值是没有意义的(例如,您可以有4行,其值为0.35,0.5,0.75和0.99,或者您可以具有35,50,75和99的值,并且结果将是相同的)。< / p>

更新:以下是您的查询的内容。您有一行cur_odds值为0.35。为了便于说明,我将假设其他9行都具有相同的值(0.072)。同样为了说明,让我们假设RAND()返回一个从0.0到1.0的值(实际上可能)。

每次运行此SELECT语句时,通过将其cur_odds值乘以从0.0到1.0的RAND()值,为每一行分配一个排序值。这意味着具有0.35的行将具有介于0.0和0.35之间的排序值。

每隔一行(值为0.072)的排序值介于0.0和0.072之间。这意味着您的一行排序值大于0.072的概率大约为80%,这意味着没有可能任何其他行可以排序更高。这就是为什么cur_odds值为0.35的行首先出现的频率超出预期。

我错误地将cur_odds值描述为相对更改权重。它实际上起到最大相对权重的作用,然后需要一些复杂的数学来确定所涉及的实际相对概率。

我不确定你需要用直接T-SQL做什么。我已多次实施一个加权概率选择器(我甚至会在今天早上提出一个关于最佳方法的问题,具有讽刺意味),但总是在代码中。