Я думаю, что это будет работать в прямом SQL; это ужасно неэффективно, а PL / SQL может быть и не таким. Это также полностью статично; различные соотношения требуют различного числа выбранных значений.
select value
from (
select mod(value, 2) + 1 as value,
row_number() over (partition by
case mod(value, 2) = 1
then 1
else 0
end) as twos_row,
row_number() over (partition by
case mod(value, 2) = 0
then 1
else 0
end) as ones_row
from (select dbms_crypto.randominteger as value
from dba_objects
order by object_id
)
)
where twos_rows <= 2
or ones_rows <= 4
Самый внутренний выбор захватывает большой стек случайных чисел. Следующий запрос определяет, будет ли это случайное значение 2 или 1, изменяя раннее случайное значение. Последний уровень вложенности просто отфильтровывает все строки после того, как было возвращено правильное число строк этого типа.
Это непроверенный и хрупкий. Если вам нужно надежное и высокопроизводительное решение, я бы порекомендовал PL / SQL, где вы
- петля
- снимать случайные числа
- определяет, к какому разделу в вашем наборе значений они будут подходить
- сохранить их, если этот раздел не был удовлетворен
- выйти, когда все разделы будут выполнены.