我想显示“问题”表的10行,其中type_id = 1的问题概率为0.2,type_id = 2的问题概率为0.8。 在我的要求下,如何增加概率?
$query = "select * from questions ORDER BY RAND() LIMIT 10";
我想显示10个问题,其中20%的问题是type_id = 2,而80%的问题是type_id = 1。
有人可以帮我吗?
答案 0 :(得分:1)
正如我在评论中指出的那样,如果要包含概率或类似的东西,将无法使用像ORDER BY RAND()
这样明显的东西。 ORDER BY RAND()
根本不支持这种事情。 ORDER BY RAND()
的运行速度也很慢,而且无论如何都不能真正用于任何大小的数据库。
您可以使用很多方法来对加权或概率进行随机排序;我不会尝试全部讨论;我只会给您一个相对简单的方法,但是请注意,最适合您的技术取决于您的特定用例。
一种简单的方法如下:
weight
或类似名称的新整数字段。现在您可以选择随机记录,每个记录的权重如下:
SELECT * FROM questions
WHERE weight >= FLOOR(RAND() * (SELECT MAX(weight) FROM questions))
ORDER BY weight
LIMIT 1
(请注意,我正在写这篇文章,很急,没有资源可以对其进行测试;我没有运行此查询,所以我可能语法错误,但是基本技巧是合理的)
这将选择一个介于零和最大weight
值之间的随机数,然后查找具有最接近该随机数weight
的问题记录。
此外,由于为weight
字段建立了索引,因此该查询将快速高效。
此技术的缺点:假定任何给定记录的权重都不会改变。如果确实需要更改记录的权重,则必须在索引中的每个记录之后更新权重值。
[编辑]
让我们想象一个像这样的表:
id Name
1 Question One
2 Question Two
3 Question Three
4 Question Four
5 Question Five
在此示例中,我们希望问题1和2的概率为0.2,问题3的概率为0.1,问题4和5的概率为0.3。这些概率可以通过将它们乘以100来表示为整数。(乘以10也可以,但是100意味着我们也可以拥有0.15之类的概率)
我们添加weight
列和它的索引,并如下设置weight
值:
id Name Weight
1 Question One 20
2 Question Two 40 (ie previous value + 20)
3 Question Three 50 (ie previous value + 10)
4 Question Four 80 (ie previous value + 30)
5 Question Five 110 (ie previous value + 30)
现在我们可以运行查询了。
查询FLOOR(RAND() * (SELECT MAX(weight) FROM questions))
的随机部分将选择一个介于0到110之间的值。我们假设它给出了68
。
现在我们其余的查询说要选择weight
大于68的第一条记录。在这种情况下,这意味着我们得到的记录是记录#4。
这给了我们概率,因为随机数可以是任意值,但是如果给定记录的权重与前一个权重之间的差距较大,则更有可能选择给定记录。获得记录4的频率是记录3的三倍。