Php 从表中随机选择一行,但有几率吗?
我有一个表格,描述了我的系统中的各种对象(如雨伞、靴子、书包等)。这些对象中的每一个都需要有不同的流行率或发病率。例如,雨伞比靴子更稀有。基于这些因素,我需要根据关联值随机选择单个对象(包括空白或“未找到对象”) 哎呀。有道理吗Php 从表中随机选择一行,但有几率吗?,php,mysql,codeigniter,Php,Mysql,Codeigniter,我有一个表格,描述了我的系统中的各种对象(如雨伞、靴子、书包等)。这些对象中的每一个都需要有不同的流行率或发病率。例如,雨伞比靴子更稀有。基于这些因素,我需要根据关联值随机选择单个对象(包括空白或“未找到对象”) 哎呀。有道理吗 SELECT * FROM some_table WHERE (100*RAND()) > some_table.percent_probability LIMIT 1 ..并且选择概率存储在百分比概率字段中 C.我将修改symcbean对此的回答,+1表示sy
SELECT * FROM some_table
WHERE (100*RAND()) > some_table.percent_probability
LIMIT 1
..并且选择概率存储在百分比概率字段中
C.我将修改symcbean对此的回答,+1表示symcbean
SELECT * FROM some_table
WHERE (100*RAND()) < some_table.percent_probability
如果您有一个写-很少-读-多场景(即,您很少更改对象和概率),您可能希望预先计算概率值,以便如果您有一个随机值,您可以明确地决定选择哪个对象(使用一个拾取,无需排序,无需对所有记录进行比较) 例如(每磨机的概率)
伞:500‰的机会
靴子:250‰的几率
背包:100‰几率
无论如何:100‰的机会
“没有”:50‰的机会 一个介于0和499之间的随机数意味着“伞”已经被选中,500-749“靴子”等等
INSERT INTO foo (name, randmin, randmax) VALUES
('umbrella', 0, 499),
('boots', 500, 749),
('satchel', 750, 849),
('whatever', 850, 949)
每次添加对象或修改概率时,都会重新创建此表
那么您只需要一个查询,如
SELECT
f.name
FROM
(
SELECT Round(Rand()*1000) as r
) as tmp
JOIN
foo as f
ON
r BETWEEN f.randmin and f.randmax
LIMIT
1
只需生成一个随机值,MySQL就可以使用(randmin,randmax)上的索引快速查找记录。不选择对象的概率应该是多少?这是存储在数据库中还是一个硬编码常量?这听起来可行,但有误导性。例如,如果您有5个对象,每个对象的概率为20%(认为每个对象应在20%的时间内显示),那么一个项目将在80%的时间内返回,在20%的时间内不返回任何内容,而其他4个项目将永远不会返回。您必须为每个项赋予0、20、40、60和80的概率,以使它们具有相等的机会。@语法错误:是的,您部分正确-经过思考,数学比您建议的要复杂一些,但通过按随机顺序排列,并将过滤器从何处(排序前)移动到having子句(即排序后),很容易修复。非常感谢:我正在快速尝试,看起来不错,但是当只返回一个结果时,我得到了一个偏移量错误?“消息:未定义偏移量:1”Me=哑。知道了。rand()函数从1开始,因此在[0]处缺少第一个键。编辑以修复未定义的偏移错误。谢谢你指出这一点。这个解决方案也有一个问题。第二个随机变量扭曲了几率。例如,如果您有10条记录,其中包含100、90、80。。。赔率和sql随机数为0.01,那么它将请求整个数据集。。。然后php随机给所有记录的几率相等。因此,有“10%几率”的记录有10%的几率来自sql,然后因为有10条记录,它有10%的几率来自PHP随机,因此它变为1%。
SELECT
f.name
FROM
(
SELECT Round(Rand()*1000) as r
) as tmp
JOIN
foo as f
ON
r BETWEEN f.randmin and f.randmax
LIMIT
1