首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从MySQL中选择随机行(有概率)

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

Stack Overflow用户
提问于 2010-04-27 03:14:57
回答 2查看 2.9K关注 0票数 6

我有一个MySQL表,其中有一个名为cur_odds的行,它是一个百分数,表示该行被选中的概率。例如,当您运行100个查询时,我如何创建一个查询,使其以大约相同的频率选择行?

我尝试了以下方法,但概率为0.35的行最终被选中的概率约为60-70%。

代码语言:javascript
复制
SELECT * FROM table ORDER BY RAND()*cur_odds DESC

表中cur_odds的所有值恰好相加为1。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-04-27 04:47:37

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

1)新建一个列prob_sum,该列

prob_sum := cur_odds

对于1 <= I <= row_count - 1:

prob_sumi := prob_sumi -1+ cur_oddsi

2)生成一个从0到1的随机数:

rnd := rand(0,1)

3)找到prob_sum > rnd的第一行(如果在prob_sum上创建BTREE索引,查询速度会快得多):

CREATE INDEX prob_sum_ind ON (prob_sum);

设置@rnd := RAND();

SELECT MIN( prob_sum ) FROM WHERE prob_sum> @rnd;

票数 4
EN

Stack Overflow用户

发布于 2010-04-27 03:23:03

对于上面的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语句时,通过将行的RAND值乘以cur_odds ()值(从0.0到1.0 ),为每行分配一个排序值。这意味着具有0.35的行将具有介于0.0和0.35之间的排序值。

每隔一行(值为0.072)将有介于0.0和0.072之间的排序值。这意味着您的一行的排序值大于0.072的可能性约为80%,这意味着没有任何其他行的排序值可能更高。这就是为什么cur_odds值为0.35的行排在第一位的次数比您预期的要多。

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

我不确定您需要的东西是否可以用直接的T-SQL来完成。我已经实现了很多次加权概率选择器(具有讽刺意味的是,我今天早上甚至要问一个关于最佳方法的问题),但总是在代码中实现。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2716163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档