【问题标题】:Auto generating time interval records自动生成时间间隔记录
【发布时间】:2020-06-20 21:20:39
【问题描述】:

我有下面的表定义和 INSERT 语句,可以正常工作。

create table.    tour_detail (
  location_id NUMBER(4),
  time interval day to second
  )

insert into tour_detail.    
(location_id,time)
 values (3, interval '11:30' hour to minute)

您下面示例中的 CTE 是否可以修改 tour_detail 表以执行以下操作。

  • 修改它以仅保留 HH24:MI 设置,其余字段 = 0。

  • 时间如何像 val = val + rand(6,12) 分钟一样相互依赖。

  • 如果 val >= 23:45 可以将其重置为随机 HH24:MI。

  • 可以为每个 tour_hdr(tour_id) 生成随机数 (15-25) 的 tour_detail 行。生成这些行时,仅使用位置 ID 行 where location_type = 'G'

  • 需要保证相同的location_id不连续

我目前正在保留 tour_detail (tour_time) MMDDYYYY HH24:MI:SS,我只需要 HH:SS。

 ALTER SESSION SET.  NLS_DATE_FORMAT = 'MMDDYYYY HH24:MI:SS';



CREATE TABLE locations AS
SELECT level AS location_id,
   'Door ' || level AS location_name,

CASE.    round(dbms_random.value(1,3)) 
        WHEN 1 THEN 'A' 
        WHEN 2 THEN 'T' 
        WHEN 3 THEN 'G' 
     END AS location_type

FROM   dual
CONNECT BY level <= 25;


ALTER TABLE locations 
     ADD ( CONSTRAINT location_id_pk
   PRIMARY KEY (location_id));


CREATE TABLE tour_hdr AS
SELECT level AS tour_id,
   'Tour ' || level AS tour_name
FROM   dual
CONNECT BY level <= 15;


 ALTER TABLE tour_hdr
     ADD ( CONSTRAINT tour_hdr_id_pk
   PRIMARY KEY (tour_id));


create table tour_detail 
(
      tour_id NUMBER(4),
      tour_time DATE,
      location_id NUMBER(4)
 )

declare
  v_loc number;      
  v_prev_loc number := 0;
  v_dt date := trunc(sysdate);
  v_dt_save date := trunc(sysdate);
begin

 for trs in ( select tour_id  from tour_hdr)
  loop

   -- for each  tour generate 15 to 25 rows
    for i in 1..dbms_random.value(15, 25) loop
   
    
   -- If date >23:45:00 reset. Should I
  -- interval be used instead of date

   IF v_dt > (v_dt_save + (1/1440*1425))
   THEN 
   
      -- reset time 
        v_dt :=  v_dt_save;

    ELSE

    -- increase last used date by random 6 to 12 minutes
      
   v_dt := v_dt + dbms_random.value(6,12)/(24*60);

   END IF;

 -- get random location
  select location_id 
    into v_loc 
    from (select location_id from locations where location_type = 'G' order by dbms_random.value) 
    where rownum = 1;

   IF v_prev_loc != v_loc
   THEN
        insert into tour_detail (tour_id, tour_time, location_id)
       values (trs.tour_id, v_dt, v_loc);
       v_prev_loc := v_loc;
    END IF;

  end loop;
 end loop;
end;

我的目标是从 tour_detail 中提取一条记录,并为 access_history 表找到一条记录,看看守卫是否及时、早、晚、没有到达那个位置。简而言之,我需要将 MMDDYYYY HH24:MI:SS 与时间间隔行进行比较。会不会很难完成

【问题讨论】:

  • 所有记录都应该有相同的location吗?
  • 不,我在另一条评论中提供了更多详细信息。希望 cmets 可以允许更多文本。这种方式很难沟通。感谢您的耐心和专业知识

标签: sql oracle date intervals recursive-query


【解决方案1】:

不清楚你真正想要哪个结果,以及location_id 应该是固定的还是随机的(如果是,如何?)。

如果您希望生成具有随机间隔值的给定行数,则可以选择使用递归 cte 和 dbms_random.value。您需要确定间隔的最大长度和迭代次数。例如,这会为您提供 10 条记录,间隔最长为 12 小时:

with cte(rnd, n) as (
    select dbms_random.value, 1 from dual
    union all
    select dbms_random.value, n+ 1 from cte where n < 10
)
select 3 as location_id, rnd * 12 * interval '1' hour as time
from cte order by n

只需在查询的最开头添加以下行,即可将其转换为 insert 语句:

insert into tour_detail (location_id, time)
with ...
select ...

Demo on DB Fiddle

LOCATION_ID |时间 ----------: | :----------------- 3 | +00 07:13:32.262069 3 | +00 03:45:18.965145 3 | +00 07:13:41.394986 3 | +00 02:24:19.516714 3 | +00 11:38:16.000109 3 | +00 11:11:47.947329 3 | +00 08:14:54.641965 3 | +00 02:52:43.090595 3 | +00 03:44:26.418538 3 | +00 09:29:35.390110

【讨论】:

  • 在你的问题中包含这些细节会很好,不是每个人都会在 cmets 中找到它们。
  • 澄清了我原来的帖子。感谢您的建议
  • @GMB 你的小提琴看起来不错,但我有几个问题。如何更改代码以仅保留 HH24:MI 设置,其余字段 = 0。其次,时间如何相互依赖,如 val = val + rand(6,12) 分钟。第三,如果 val >= 23:45 可以休息到一些随机的 HH24:MI。感谢您的专业知识和耐心
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多