SQL根据百分比分配随机数

时间:2012-05-07 20:33:25

标签: sql oracle oracle10g

我有一个包含userId和username的表。我想根据百分比为每一行分配随机数。例如:我想为每一行分配6,7,8。但是50%的记录应该分配6个。 45%的行应该分配7个,剩下的5%的行应该分配8个。

我们有可能在SQL中执行此操作吗?

输出应为userid,username,random number。

3 个答案:

答案 0 :(得分:2)

  select userid, username, case cast (dbms_random.value(0, 20) as int) 
    when 0 then 6
    when 1 then 6
    when 2 then 6
    when 3 then 6
    when 4 then 6
    when 5 then 6
    when 6 then 6
    when 7 then 6
    when 8 then 6
    when 9 then 6
    when 10 then 7
    when 11 then 7
    when 12 then 7
    when 13 then 7
    when 14 then 7
    when 15 then 7
    when 16 then 7
    when 17 then 7
    when 18 then 7
    when 19 then 8
    else -1 -- should never happen
 end as "RANDOM" 
   from mytable;

因为这些值是随机生成的,所以这不会给你50/45/5的比例,但是如果你有大量的行(并且随机数函数有任何好处),它应该接近它。

另一种方法是order by random行,并将6分配给前50%,将7分配给下一个45%,将剩余分配给8。这将确保您具有正确的比率:

with myset as (
    select userid, username
    from my_user_table
    order by dbms_random.value(0,1)
)
select * from
(
    select 
        userid, 
        username, 
        case when rownum <= (select count(*) from myset) * 0.50 then 6
            when rownum <= (select count(*) from myset) * 0.95 then 7
            else 8 
          end as random
    from myset) t
order by t.userid;

答案 1 :(得分:2)

如果PL / SQL是一个选项:

DECLARE
  RAND number := dbms_random.value;
BEGIN
  IF RAND <= 0.50 THEN
     RAND := 6;
  ELSIF RAND <= 0.95 THEN
     RAND := 7;
  ELSE
     RAND := 8;
  END IF;
  dbms_output.put_line(RAND); -- this line can be changed by the 'insert'
END;

答案 2 :(得分:1)

我发现分配随机数的最佳方法是通过伪随机数生成器:

  1. 枚举每一行
  2. 计算公式以获得伪随机数
  3. 使用此选项选择适当的范围
  4. 对于你的情况:

    SELECT t.*, 
           ( CASE 
               WHEN Mod(rownum * 71 + 107, 257) < .5 * 257 THEN 6 
               WHEN Mod(rownum * 63 + 107, 257) BETWEEN 0.5 * 257 AND 0.95 * 257 
             THEN 7 
               ELSE 8 
             END ) AS val 
    FROM   (SELECT t.*, 
                   Row_number() 
                     OVER ( 
                       partition BY NULL) AS rownum 
            FROM   t) t 
    

    这个想法是乘以一个素数,加上另一个素数,并将余数乘以三分之一是随机数的非常好的近似值。不完美,但足以满足大多数目的。

    此外,这里的百分比是近似值。

相关问题