将前一行减去时间戳数据类型的当前行
Subtracting previous row to current row of timestamp datatype
我需要从(之前的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 function doesn't help in date datatype.
不,那不对,您可能正在寻找这样的东西。
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;
根据您的描述,您比较的方式似乎是错误的;您的 where-clause 过滤器正在根据其实际开始时间和持续时间 - 而不是之前 在 完成上一个作业后查找请求的日期。
所以您或许可以将逻辑更改为:
where cast(A.req_start_date as date) < (cast(B.ACTUAL_START_DATE as date) + b.run_duration)
不过我不确定您为什么要将时间戳转换为日期;你正在失去精度,这可能意味着你错过了 运行 非常接近(sub-second 差距)的工作。在我的测试实例中,我看到 23 条带有这些转换的记录 - 全部来自 ORACLE_APEX_MAIL_QUEUE
- 但如果我将它们保留为时间戳,则为 36 条。
您也可以根据行号使用 lag()
而不是 self-joining:
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;
这给出了 'consumption' 作为一个区间 - 正数,因为我也在该减法中切换了术语。
结果目前仅包括上一行的实际开始日期和持续时间;如果您想要其他字段,那么您也可以为这些字段包含滞后条款。我也会避免 *
,但我不知道您真正对当前行或上一行中的哪些列感兴趣。
使用下面的查询来获取在 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;
我需要从(之前的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 function doesn't help in date datatype.
不,那不对,您可能正在寻找这样的东西。
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;
根据您的描述,您比较的方式似乎是错误的;您的 where-clause 过滤器正在根据其实际开始时间和持续时间 - 而不是之前 在 完成上一个作业后查找请求的日期。
所以您或许可以将逻辑更改为:
where cast(A.req_start_date as date) < (cast(B.ACTUAL_START_DATE as date) + b.run_duration)
不过我不确定您为什么要将时间戳转换为日期;你正在失去精度,这可能意味着你错过了 运行 非常接近(sub-second 差距)的工作。在我的测试实例中,我看到 23 条带有这些转换的记录 - 全部来自 ORACLE_APEX_MAIL_QUEUE
- 但如果我将它们保留为时间戳,则为 36 条。
您也可以根据行号使用 lag()
而不是 self-joining:
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;
这给出了 'consumption' 作为一个区间 - 正数,因为我也在该减法中切换了术语。
结果目前仅包括上一行的实际开始日期和持续时间;如果您想要其他字段,那么您也可以为这些字段包含滞后条款。我也会避免 *
,但我不知道您真正对当前行或上一行中的哪些列感兴趣。
使用下面的查询来获取在 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;