繁体   English   中英

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

[英]Select random row from MySQL (with probability)

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

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

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

表中cur_odds的所有值都精确地加1。

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

1) prob_sum创建另一列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> WHERE prob_sum> @rnd;

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

更新:这是您的查询正在发生的事情。 你有一行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之间。 这意味着,存在约80%的机会,你的一排将有一个排序值大于0.072时,这将意味着没有可能的机会 ,任何其他行可能进行排序更高。 这就是为什么你的cur_odds值为0.35的行比你预期的更频繁。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM