我有一个包含userId和username的表。我想根据百分比为每一行分配随机数。例如:我想为每一行分配6,7,8。但是50%的记录应该分配6个。 45%的行应该分配7个,剩下的5%的行应该分配8个。
我们有可能在SQL中执行此操作吗?
输出应为userid,username,random number。
答案 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)
我发现分配随机数的最佳方法是通过伪随机数生成器:
对于你的情况:
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
这个想法是乘以一个素数,加上另一个素数,并将余数乘以三分之一是随机数的非常好的近似值。不完美,但足以满足大多数目的。
此外,这里的百分比是近似值。