Как наполнить таблицу случайными записями, если id нужно брать из другой таблицы случайно?
Как наполнить таблицу 10000 случайными записями, при том что id (empno) нужно брать из другой таблицы в случайном порядке? Где id четырехзначные числа, идут не по порядку.
Код ниже выводит один id на все 10000 записей. Была идея через level, но все равно выводит один id на все записи, хоть убирай level, хоть оставляй, одно и тоже.
insert into prodal
(kto_prodal, tovar_id, kol_vo, p_data)
SELECT
((select empno
from (select empno from emp order by dbms_random.value)
where rownum = 1)+level-level),
dbms_random.value(1, 5),
dbms_random.value(1, 20),
(to_date(sysdate, 'dd.mm.yyyy hh24:mi:ss')
+dbms_random.value(1, 365)
+dbms_random.value(1, 23) / 24
+dbms_random.value(1, 59) / 24 / 60 )
FROM dual connect by level <= 10000;
Вот что получается. Справа столбец empno, из которого надо взять id и рандомно вставить на 10000 срок с повторением:
Еще условие, можно использовать только один dml запрос.
Ответы (1 шт):
Вот та часть запроса, которая вызывает проблему:
create table emp (empno) as
select column_value from sys.odciNumberList (7369,7499,7566,7788)
/
select (
select empno from (
select empno
from emp
order by dbms_random.random) where rownum = 1) empno
from dual d connect by level <= 10
/
EMPNO
----------
7369
7369
[...]
7369
10 rows selected.
Вы ожидали, что подзапрос выполнится в каждой строке N раз. Но это не так.
Между основным запросом и скалярным подзапросом нет корреляции, поэтому оптимизатор решил выполнить подзапрос только один раз и выводить его результат в каждой строке основного запроса.
Самое простое, встроить в подзапрос корреляцию с основным запросом, условие для которой всегда выполнится в true.
Или так:
select (
select empno from (
select empno
from emp
order by dbms_random.random) where s.lvl is not null and rownum = 1) empno,
date'2021-01-01'+numToDsInterval(trunc(dbms_random.value(0, 60*24*365)),'minute') dt
from (select level lvl from dual connect by level <= 10) s
Или лучше так:
select (
select max (empno) keep (dense_rank first order by dbms_random.random)
from emp where s.lvl > 0) empno,
date'2021-01-01'+numToDsInterval(trunc(dbms_random.value(0, 60*24*365)),'minute') dt
from (select level lvl from dual connect by level <= 10) s
Результат будет выглядеть примерно так:
EMPNO DT
---------- -------------------
7499 2021-03-31 04:26:00
7566 2021-08-31 15:59:00
[...]
7788 2021-10-05 09:54:00
10 rows selected.
