【问题标题】:Selecting MySQL records with chance有机会选择 MySQL 记录
【发布时间】:2013-07-05 03:09:12
【问题描述】:

我有一个包含 3 个字段的 MySQL 表,如下所示。

id, name, chance
1001, name1, 1
1002, name2, 3
1003, name3, 1

我想随机选择一条记录 100 次。在 100 次中,我希望记录 id 1001 被选择 20 次(1/5 机会),记录 id 1002 被选择 60 次(3/5 机会),记录 id 1003 被选择 20 次(1/5机会)。

如何在 MySQL 和/或 PHP 中做到这一点?

非常感谢!

【问题讨论】:

    标签: php mysql sql algorithm


    【解决方案1】:

    在php中生成随机数

    int rand ( int $min , int $max )
    

    然后使用一系列 if 语句。

    例如:

    $random = rand (1,100);
    (INSERT LOOP)
    if ($random <= 20){
    $id1001 = $id1001 + 1;
    }
    else if ($random > 20 and $random < 80){
    $id1002 = $id1002 + 1;
    }
    else if ($random > 80 and $random < 100){
    $id1003 = $id1003 + 1;
    }
    (END LOOP)
    

    【讨论】:

      【解决方案2】:

      在 SQL 中执行此操作有点挑战性。如果您的数字真的很小,最简单的方法是通过 cross join 将记录相乘,然后从那里随机抽取一行:

      select t.*
      from t join
           (select 1 as n union all select 2 union all select 3) n
           on n.n <= t.chance
      order by rand()
      limit 1;
      

      如果“机会”是一个小整数,则此方法有效。

      否则,我认为您需要累积机会总​​和,然后进行比较。比如:

      select t.*
      from (select t.*, (@sumchance := @sumchance + chance) as sumchance
            from t cross join (select @sumchance := 0) const
           ) t cross join
           (select sum(chance) as totchance from t) tot
      where rand()*totchance between sumchance - chance and sumchance
      limit 1;
      

      这会计算给定行的机会总和(顺序没有区别,因为这是随机的)。然后它计算相同范围内的随机数并将其与sumchance - chancechance 进行比较。这应该返回一行,但存在rand()*totchance 完全等于sumchance 的边界情况。可以返回任一行。 limit 1 将其限制为一行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-12
        • 2020-09-15
        • 1970-01-01
        • 2018-11-19
        • 2016-01-27
        • 2011-09-25
        • 1970-01-01
        相关资源
        最近更新 更多