我有一个MySQL表,其中有一行名为cur_odds,这是一个百分数,该行的概率百分比将被选中。例如,当您运行100个查询时,如何进行实际选择大约该频率的行的查询?
我尝试了以下操作,但是有一个概率为0.35的行最终会在60-70%的时间内被选中。
SELECT * FROM table ORDER BY RAND()*cur_odds DESC
表格中cur_odds的所有值恰好合计为1。
答案 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做什么。我已多次实施一个加权概率选择器(我甚至会在今天早上提出一个关于最佳方法的问题,具有讽刺意味),但总是在代码中。