random 패키지 관련 문제를 이 thread에서 정리하도록 한다.
첫번째 문제는,
랜덤하게 1부터 s까지 출력하되, 특정 숫자가 다른 숫자에 비해 r배 많이 나오도록 하는 것이다.
쿼리는 아래와 같다.
-- s: 1부터 s까지의 정수를 출력
-- n: 다른 숫자보다 더 많이 나오도록 할 그 숫자
-- r: n이 r배 많이 나오도록 한다.
with t as (
select 10 s, 7 n, 3 r from dual)
select ceil(v/r), count(*)
from
(
select n,r,s*r*dbms_random.value v
from t
connect by level<=100000*(1+(r-1)/10)
)
where ceil(v/r)=n or v/r<=ceil(v/r)-1+1/r
group by ceil(v/r)
order by 1
여기서는 출력된 숫자들의 배수 관계를 확인하기 위해서 group by후 count했다
결과는...
CEIL(V/R) COUNT(*)
---------- ----------
1 3925
2 3919
3 3990
4 4036
5 3908
6 3981
7 11967
8 4000
9 3996
10 3971
7이 다른 숫자에 비해 거의 3배 더 출력되었다.
혹은,
위의 해법은 where절에서 잘려나가는 불필요한 데이터가 많으므로,
아래와 같이 필요한 크기만큼만 더 늘려서 생성한다.
with t as (
select 10 s, 7 n, 10 r from dual)
select case when ceil(v)>s then n else ceil(v) end p
, count(*), sum(count(*)) over () t
from
(
select n,r,s,(s+r-1)*dbms_random.value v
from t
connect by level<=100000*(1+(r-1)/10)
)
group by case when ceil(v)>s then n else ceil(v) end
order by 1
결과는
P COUNT(*) T
---------- ---------- ----------
1 10127 190000
2 10014 190000
3 9942 190000
4 9859 190000
5 9958 190000
6 10079 190000
7 100021 190000
8 10028 190000
9 9957 190000
10 10015 190000
위의 두 쿼리는 약간의 오류가 있으므로 아래 쿼리로 대체한다.
with t as (
select 10 s, 7 n, 3 r from dual)
select case when trunc(v)>s then n else trunc(v) end p
, count(*), sum(count(*)) over () t
from
(
select n,r,s,dbms_random.value(1,s+r) v
from t
connect by level<=100000*(1+(r-1)/10)
)
group by case when trunc(v)>s then n else trunc(v) end
order by 1