SQL根据百分比选择随机行

时间:2018-05-31 20:08:06

标签: mysql sql

基本上,我需要一个随机数发生器,但不是平等地处理所有行(每行25%),而是需要根据分配给它的百分比来处理它。

例如:

Event Chance_Percentage
A          25.00
B          10.00
C          15.00
D          50.00

我将如何实现这一目标?

我正在使用MySQL。

5 个答案:

答案 0 :(得分:0)

我没有在我的机器上安装MySQL,所以这是未经测试的,但我认为这个一般性的想法是可行的。

    SELECT Event
      FROM Your_Table
     WHERE CASE WHEN Event = 'A' THEN 
                CASE WHEN RAND() <= .25 THEN 1
                     END
                WHEN Event = 'B' THEN 
                CASE WHEN RAND() <= .1 THEN 1
                     END
                WHEN Event = 'C' THEN 
                CASE WHEN RAND() <= .15 THEN 1
                     END
                WHEN Event = 'D' THEN 
                CASE WHEN RAND() <= .5 THEN 1
                     END
            END = 1;

答案 1 :(得分:0)

这应该很容易在Java,Python,C,php,JavaScript或您正在使用的其他应用程序编程语言中进行计算。您可以在应用程序中选择所有行,并在那里进行计算,以便于编写。

如果数据库中没有应用程序需要执行,则不要这样做。使用正确的工具来完成正确的工作。数据库首先是持久性而不是计算。

另请参阅XY problem

答案 2 :(得分:0)

更通用的解决方案是:

select e.*, t2.*
  from (
    select event,
      (select coalesce(sum(chance_percentage), 0) 
         from table1 t2 where t2.event < t1.event) as lower_bound,
      (select sum(chance_percentage) 
         from table1 t3 where t3.event <= t1.event) as upper_bound
      from table1 t1) e
  join (select 100.0 * rand() as p) t2
    where t2.p >= e.lower_bound and t2.p < e.upper_bound;

答案 3 :(得分:0)

如果您只想选择一个proba等于百分比

的字段

我认为这样的事情会很好:     设置@mybound:= RAND()* 100;     SELECT * FROM事件,其中Chance_Percentage&lt; @mybound     ORDER BY Chance_Percentage desc limit 1

答案 4 :(得分:0)

执行累计求和,然后运行rand()一次:

select t.event
from (select t.*, (@cume_p = @cume_p + p) as cume_p
      from t cross join
           (select @cume_p := 0, @rand = rand()) params
     ) t
where @rand >= cume_p - p and
      @rand < cume_p;

请注意rand()只调用一次。该值存储在变量中;这是一个随意的选择。它也可以在子查询中:

select t.event
from (select t.*, (@cume_p = @cume_p + p) as cume_p
      from t cross join
           (select @cume_p := 0) params
     ) t cross join
     (select rand() as r) r
where r.r >= cume_p - p and
      r.r < cume_p;