1

userIdとusernameのテーブルがあります。パーセントに基づいて各行に乱数を割り当てたいと思います。例:各行に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 の比率が正確に得られるわけではありませんが、多数の行がある場合 (および乱数関数が適切である場合) はそれに近いはずです。

もう 1 つの方法はorder by random、行に対して、最初の 50% に 6 を割り当て、次の 45% に 7 を割り当て、残りに 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 

1 つの素数を掛けて別の素数を足し、残りを 3 分の 1 でとることは、乱数のかなり良い近似であるという考え方です。完璧ではありませんが、ほとんどの目的には十分です。

また、ここでのパーセンテージは概算です。

于 2012-05-07T20:41:30.143 に答える