我需要从(上一个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)
但不确定输出。
有人可以帮忙吗?
答案 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;