将前一行减去当前时间戳数据类型的行

时间:2018-03-20 14:37:09

标签: oracle date datetime jobs job-scheduling

我需要从(上一个ACTUAL_START_DATE + RUN_DURATION)中减去当前的REQ_START_DATE,以便在完成上一次执行之前检查作业是否被请求的时间。

尝试使用以下查询:

WITH delay_in_start AS (
SELECT  LOG_ID, LOG_DATE, OWNER, JOB_NAME, REQ_START_DATE, ACTUAL_START_DATE,run_duration, ROW_NUMBER() OVER (PARTITION BY job_name ORDER BY req_start_date desc) RN
FROM dba_scheduler_job_run_details t
)
SELECT cast(A.req_start_date as date) - cast((B.ACTUAL_START_DATE + b.run_duration)  as date) Consumption, a.*, b.*
FROM delay_in_start A LEFT JOIN delay_in_start B 
    ON B.JOB_NAME = A.JOB_NAME 
    AND A.RN  = B.RN - 1
    where cast(A.req_start_date as date) > (cast(B.ACTUAL_START_DATE as date) + b.run_duration)

但不确定输出。

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:2)

根据您的描述,您似乎在比较错误的方式;你的where子句过滤器在完成上一个作业之后,根据它的实际开始时间和持续时间来寻找之前的请求日期 - 而不是之前。

所以你可以将逻辑改为:

where cast(A.req_start_date as date) < (cast(B.ACTUAL_START_DATE as date) + b.run_duration)

我不知道你为什么把时间戳投射到日期;你失去了精确度,这可能意味着你错过了非常接近的工作(亚秒级差距)。在我的测试实例中,我看到有23个记录与这些演员 - 全部来自ORACLE_APEX_MAIL_QUEUE - 但如果我把它们作为时间戳留下36个。

您还可以使用lag()代替基于行号的自加入:

select lag_actual_start_date + lag_run_duration - req_start_date as consumption,
  t.*
from (
  select dba_scheduler_job_run_details.*,
    lag(actual_start_date)
      over (partition by job_name order by req_start_date) as lag_actual_start_date,
    lag(run_duration)
      over (partition by job_name order by req_start_date) as lag_run_duration
  from dba_scheduler_job_run_details
) t
where req_start_date < lag_actual_start_date + lag_run_duration
order by job_name, req_start_date;

将“消费”作为一个区间给出 - 为正,因为我在该减法中也改变了术语。

结果目前仅包括上一行的实际开始日期和持续时间;如果你想要其他字段,那么你也可以包含滞后条款。我也会避免使用*,但我不知道您当前或上一行实际感兴趣的列。

答案 1 :(得分:1)

  

滞后函数对日期数据类型没有帮助。

不,那不对,你可能正在寻找类似的东西。

SELECT JOB_NAME,
  CASE
    WHEN REQ_START_DATE >= LAG ( actual_start_date + run_duration ) 
     OVER ( PARTITION BY JOB_NAME ORDER BY LOG_DATE )
    THEN 1
    ELSE 0
  END
FROM dba_scheduler_job_run_details;

答案 2 :(得分:0)

在查询下方使用,以获取req_start_date和actual_start_date不同的所有作业的数据,但不包括由于之前的作业延迟而导致延迟的作业详细信息(即,如果延迟启动是由于之前的运行未完成) 谁的时间超过60秒

SELECT extract(DAY FROM(t.actual_start_date - t.req_start_date)) * 24 * 60 * 60 +
       (extract(hour FROM(t.actual_start_date - t.req_start_date))) * 60 * 60 +
       (extract(minute FROM(t.actual_start_date - t.req_start_date))) AS duration,
       t.*
FROM (SELECT d.*,
             lag(actual_start_date) over(PARTITION BY job_name ORDER BY req_start_date) AS lag_actual_start_date,
             lag(run_duration) over(PARTITION BY job_name ORDER BY req_start_date) AS lag_run_duration
      FROM dba_scheduler_job_run_details d) t
WHERE ((lag_actual_start_date IS NOT NULL AND req_start_date > lag_actual_start_date + lag_run_duration) OR -- For Jobs running at frequent time interval
      (lag_actual_start_date IS NULL AND actual_start_date > req_start_date))        -- For Jobs scheduled at single time interval
AND extract(DAY FROM(t.actual_start_date - t.req_start_date)) * 24 * 60 * 60 +
      (extract(hour FROM(t.actual_start_date - t.req_start_date))) * 60 * 60 +
      (extract(minute FROM(t.actual_start_date - t.req_start_date))) > 1
ORDER BY log_date DESC;