1

我有一个带有 userId 和用户名的表。我想根据百分比为每一行分配随机数。例如:我想为每一行分配 6、7、8。但是 50% 的记录应该分配 6 个。45% 的行应分配 7 个,其余 5% 的行应分配 8 个。

有没有办法在 SQL 中做到这一点?

输出应该是用户 ID、用户名、随机数。

4

3 回答 3

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;
于 2012-05-07T21:00:06.890 回答
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;
于 2012-05-07T20:44:47.093 回答
1

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

  1. 枚举每一行
  2. 计算公式以获得伪随机数
  3. 使用它来选择合适的范围

对于您的情况:

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 

这个想法是,乘以一个素数,加上另一个素数,然后通过三分之一取余数是随机数的一个很好的近似值。不完美,但对于大多数用途来说已经足够了。

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

于 2012-05-07T20:41:30.143 回答