Решение зависит, если вы хотите, чтобы все строки из первого начального набора (-ов) и случайные дополнительные строки из последнего, использовали:
with params(size_, sample_) as (select 4, 6 from dual)
select val
from (
select mod(level - 1, size_) + 1 val, sample_,
case when level <= size_ * floor(sample_ / size_) then 0
else dbms_random.value()
end rand
from params
connect by level <= size_ * ceil(sample_ / size_)
order by rand)
where rownum <= sample_
Но если вы разрешите возможность результата, например (1, 1, 2, 2, 3, 3), где некоторые значения могут вообще не отображаться в выводе (здесь 4
), тогда используйте это:
with params(size_, sample_) as (select 4, 6 from dual)
select val
from (
select mod(level - 1, size_) + 1 val, sample_, dbms_random.value() rand
from params
connect by level <= size_ * ceil(sample_ / size_)
order by rand)
where rownum <= sample_
Как это работает?Мы строим множество (1, 2, 3, 4) столько раз, сколько это получается в результате деления sample / size
.Затем мы назначаем случайные значения.В первом случае я назначаю 0
первому набору (ям), чтобы они точно были на выходе, а случайные значения - последнему наборуВо втором случае случайности назначаются всем строкам.