我有一些代码正在生成父级,并为每个父级生成随机数量的子级记录。我希望每个父母有5条或更多的子记录,并且少于20条。
我跑了几次,但似乎没有得到或很少有5-13范围内的子记录。
有人可以解释一下我如何获得更分散的子记录价值。
如果您运行下面的最后一个查询,您将看到没有计数(*)或值6-15中的计数很少。
毫无疑问,我的逻辑有问题,但似乎找不到。我也欢迎任何完成相同任务并使用INSERT all语句生成大量子记录的新代码。
我的目标是生成大量测试数据以检查应用程序查询。目前,我只产生30天的价值。
CREATE TABLE emp_info
(
empid INTEGER,
empname VARCHAR2(50)
);
CREATE TABLE emp_attendance
(empid INTEGER,
start_date DATE,
end_date DATE
);
insert all
-- when rn=1 insert the parent record.
-- 1 will always =1 always insert a
-- child record.
when rn = 1 then into emp_info (empid, empname) values (id, name)
when 1 = 1 then into emp_attendance (empid, start_date, end_date)
values (id, d1, d1 + dbms_random.value (0, .75))
select * from
(
-- get the highest empid as start
-- so this can be run more than once.
-- if never run before start with 0.
with t as (select nvl(max(empid), 0) maxid from emp_info)
select ceil(maxid + level/20) id,
case mod(maxid + level, 20) when 1 then 1 end rn,
-- create an alpha name from 3-15
-- characters in length.
dbms_random.string('U', dbms_random.value(3, 15)) name,
-- set the start date any where from
-- today + 30 days
trunc(sysdate) + dbms_random.value (1, 30) d1,
case when row_number() over (partition by ceil(maxid + level/20) order by level) > 5 then
-- Ensure there is a minimum of
-- 5 child and a max of 20 records
-- for each parent.
--
-- Exclude first 5 records and then
-- for 6-20 records, generating
-- random number between 5-20.
-- We can then compare with any
-- number between 5-20 so that it
-- can give us any number of
-- records.
dbms_random.value(5, 20) else 5 end as random_val from t
connect by level <= 20 * 1000
)
where random_val <= 19;
-- why is this where clause neeed?
SELECT empid, count(*)
from emp_attendance
group by empid order by empid
EMPID COUNT(*)
1 20
2 20
3 20
4 18
5 19
6 20
7 20
8 19
9 20
10 20
11 19
……
50. 20
这样的事情应该可以帮助您。
SQL> with
2 emps as
3 ( select level empid, dbms_random.value(5,20) children from dual connect by level <= 20 ),
4 empatt as
5 ( select e.empid , x.start_date, x.start_date+dbms_random.value(0,0.75) end_date
6 from emps e,
7 lateral(
8 select
9 trunc(sysdate)+dbms_random.value(1,30) start_date
10 from dual
11 connect by level <= e.children
12 ) x
13 )
14 select empid, count(*)
15 from empatt
16 group by empid
17 order by 1;
EMPID COUNT(*)
---------- ----------
1 5
2 14
3 17
4 6
5 10
6 18
7 12
8 13
9 16
10 11
11 7
12 14
13 7
14 7
15 7
16 13
17 18
18 9
19 9
20 12