【问题标题】:Subtracting previous row to current row of timestamp datatype将前一行减去当前行的时间戳数据类型
【发布时间】:2018-03-20 14:37:08
【问题描述】:

我需要从 (previous 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)

但不确定输出。

有人可以帮忙吗?

【问题讨论】:

  • 您不确定什么?您没有显示任何示例数据、当前输出或预期输出,因此我们没有太多工作要做。 (另外,查看 lag 函数以查看前一行,而不是使用带有行号的子查询;您可能会发现它更简单。)
  • 滞后函数对日期数据类型没有帮助。由于 dba_scheduler_job_run_details 是作业视图并且存在于全球范围内,因此我没有提供示例。我的要求是只计算作业的 req_start_date(最后一次执行)不应该小于作业的实际开始日期 + run_duration(第二次最后执行)
  • 你对滞后的看法是错误的,但这是一个附带问题。你还没有说出你不确定的事情。如果您只想查看那些重叠的部分,您是否在 where 子句中刚刚使用了 > 而不是 <

标签: oracle date datetime jobs job-scheduling


【解决方案1】:

根据您的描述,您似乎在比较错误的方式;您的 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;

这将“消耗”作为一个区间 - 积极的,因为我在减法中也改变了术语。

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

【讨论】:

    【解决方案2】:

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

    不,这不对,您可能正在寻找类似的东西。

    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;
    

    【讨论】:

      【解决方案3】:

      在下面的查询中使用来获取 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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-10
        • 1970-01-01
        • 2021-01-04
        • 2020-12-10
        • 1970-01-01
        • 2011-10-11
        • 2015-03-23
        • 1970-01-01
        相关资源
        最近更新 更多