我希望生成时间来创建一个时间表,其中有多个位置需要检查。
想象一个狱警在监狱里走来走去,检查每一个牢房。计划将在某个随机时间mmddyyyyy hh24:mi开始,然后有6-10分钟的时间检查下一个单元格,在这6-10分钟之后检查单元格,依此类推,直到计划完成。
让我用一个简单的例子来说明。
计划\u id位置\u id计划\u时间
1 100 07132020 16:10:00
--计划开始
1 103 07132020 16:07:00
--警卫必须在16:07到达103号位置
1 110 07132020 16:16:00
--警卫必须在16:16到达110号位置
因为我随机为计划1生成了3行,所以这就完成了,然后我创建了下一个计划。
--但是假设我为这个时间表随机生成了5行。
2 102 07132020 23:46:00
--警卫必须在23:46到达102号位置
2 104 07132020 23:56:00
--警卫必须在23:56到达104号位置
--等等!!我已经为计划2生成了5行,但是下一个间隔将跨越午夜,所以我停止了2行,然后继续以随机的hh24:mi创建下一个计划,但是mmddyyyy仍然是相同的07132020。
权宜之计是要么我们把时间填到一排,要么它不能穿过午夜!!
--开始新计划。注意相同的mmddyyyy
3 223 07132020 02:04:00
3 143 07132020 02:11:00
3 46 07132020 02:17:00
你的第一个例子几乎就在那里,只是没有权宜之计阻止它穿越午夜,生成下一个时间表。
我也有一个位置表,我想随机选择一个位置标识,但我不能使用dbms\u random,因为值不是连续编号的。我会想办法的。我提到它是为了完成这个场景。
CREATE TABLE schedule_hdr AS
SELECT level AS schedule_id,
'Schedule ' || level AS schedule_name
FROM dual
CONNECT BY level <= 10;
CREATE TABLE locations(
location_id NUMBER(4),
location_name VARCHAR2(30)
);
INSERT INTO locations (
location_id,
location_name
)
VALUES
(46, 'Door 1');
INSERT INTO locations (
location_id,
location_name
)
VALUES
(143, 'Door 2');
INSERT INTO locations (
location_id,
location_name
)
VALUES
(223, 'Door 3');
WITH random_times ( schedule_id, schedule_name, datetime, lvl ) AS (
SELECT schedule_id,
schedule_name,
TRUNC(sysdate)
+ NUMTODSINTERVAL( FLOOR(DBMS_RANDOM.VALUE(0,23*60)), 'MINUTE' ),
1
FROM schedule_hdr
UNION ALL
SELECT schedule_id,
schedule_name,
datetime + NUMTODSINTERVAL(FLOOR(DBMS_RANDOM.VALUE(6,11)), 'MINUTE'),
lvl + 1
FROM random_times
WHERE lvl < 5
)
SELECT schedule_id,
schedule_name,
datetime
FROM random_times
ORDER BY schedule_id, datetime;
我的第一次尝试,但日期是。总是随机的,没有间隔
WITH rws as ( select level rn from dual connect by level <= 5 ),
scheds as ( select sh.*, round (dbms_random.value(1,5) ) n from schedule_hdr sh )
select schedule_id,
TRUNC(sysdate) + DBMS_RANDOM.value(0,86400)/86400
from rws
join scheds s on rn <= n
Order by schedule_id;
5条答案
按热度按时间mzaanser1#
这应该是你想要的:
这将生成秒数,然后将其添加到日期中。
查看时间的一种方法是将值转换为字符串:
bsxbgnwa2#
好的,整个过程如下:
它使用cte创建第一个值,然后提供一个列表,直到没有更多的值。我计算一个从0到18*60+59的随机分钟作为起始值。然后我有一个递归的cte,它在6到10分钟之间增加前面的值。递归在18:49有一个停止条件。下一个增量仍应允许小于18:59的值
rekjcdws3#
我会这样做:
abithluo4#
你可以用
NUMTODSINTERVAL( <random_amount>, 'MINUTE' )
产生几分钟的间隔。将其与递归子查询factoring子句结合,您可以为中的每一行生成5行schedule_hdr
:因此,对于您的测试数据:
这将输出:
db<>在这里摆弄
更新
我总是需要所有行的mmddyyyy都相同。因此,可以调整代码以重置计划id更改时的开始时间。
生成一组行和
CROSS JOIN
用你的table:这将提供:
db<>在这里摆弄
更新2
输出:
db<>在这里摆弄
pieyvz9o5#
免责声明:我是一名c/ms sql开发人员,从未使用过oracle sql或oracle系统,请原谅我的语法。
在生成随机数之前,需要设置一个种子。通常,ms中的时间戳是生成随机数的好种子,因为每次执行(源)的时间戳不同:
然后在生成日期时。在添加带有数字的日期时,我不确定您是否可以简单地执行+。如果是,请原谅我,否则,请尝试
numToDSInterval
(来源):