繁体   English   中英

Oracle SQL 查询逻辑 - 基于日期差异的分组依据

[英]Oracle SQL query Logic - Group by based on Date Difference

有人可以帮助实现下面描述的要求的想法:

在此处输入图片说明

上表(在屏幕截图中)维护了预定进程的作业历史记录。

我的要求是有一个目标表,按照下面的屏幕截图维护累积历史记录。

在此处输入图片说明

源/目标表结构和源示例记录sql代码参考如下:

CREATE TABLE "XHQ"."SHIFT_LOG" ("SEQUENCE_ID" NUMBER(10,0), 
"JOB_ID" NUMBER(10,0), 
"START_TS" DATE, 
"END_TS" DATE, 
"MINIMUM_VALUE" FLOAT(126), 
"MAXIMUM_VALUE" FLOAT(126), 
"AVERAGE_VALUE" FLOAT(126), 
"USERID" NVARCHAR2(80) );

Insert into XHQ.SHIFT_LOG (SEQUENCE_ID,JOB_ID,START_TS,END_TS,MINIMUM_VALUE,MAXIMUM_VALUE,AVERAGE_VALUE,USERID) values (10908,12000,to_date('01-MAY-15','DD-MON-RR'),null,null,null,null,'admin');
Insert into XHQ.SHIFT_LOG (SEQUENCE_ID,JOB_ID,START_TS,END_TS,MINIMUM_VALUE,MAXIMUM_VALUE,AVERAGE_VALUE,USERID) values (10825,12000,to_date('29-APR-15','DD-MON-RR'),to_date('01-MAY-15','DD-MON-RR'),null,null,null,'admin');
Insert into XHQ.SHIFT_LOG (SEQUENCE_ID,JOB_ID,START_TS,END_TS,MINIMUM_VALUE,MAXIMUM_VALUE,AVERAGE_VALUE,USERID) values (10800,12000,to_date('29-APR-15','DD-MON-RR'),to_date('29-APR-15','DD-MON-RR'),5,10,7.5,'admin');
Insert into XHQ.SHIFT_LOG (SEQUENCE_ID,JOB_ID,START_TS,END_TS,MINIMUM_VALUE,MAXIMUM_VALUE,AVERAGE_VALUE,USERID) values (10725,10500,to_date('28-APR-15','DD-MON-RR'),to_date('29-APR-15','DD-MON-RR'),4,8,6,'admin');
Insert into XHQ.SHIFT_LOG (SEQUENCE_ID,JOB_ID,START_TS,END_TS,MINIMUM_VALUE,MAXIMUM_VALUE,AVERAGE_VALUE,USERID) values (10625,10500,to_date('27-APR-15','DD-MON-RR'),to_date('27-APR-15','DD-MON-RR'),6,6,6,'admin');
Insert into XHQ.SHIFT_LOG (SEQUENCE_ID,JOB_ID,START_TS,END_TS,MINIMUM_VALUE,MAXIMUM_VALUE,AVERAGE_VALUE,USERID) values (10620,10500,to_date('23-APR-15','DD-MON-RR'),to_date('27-APR-15','DD-MON-RR'),null,null,null,'admin');
Insert into XHQ.SHIFT_LOG (SEQUENCE_ID,JOB_ID,START_TS,END_TS,MINIMUM_VALUE,MAXIMUM_VALUE,AVERAGE_VALUE,USERID) values (10525,10500,to_date('22-APR-15','DD-MON-RR'),to_date('23-APR-15','DD-MON-RR'),null,null,null,'admin');
Insert into XHQ.SHIFT_LOG (SEQUENCE_ID,JOB_ID,START_TS,END_TS,MINIMUM_VALUE,MAXIMUM_VALUE,AVERAGE_VALUE,USERID) values (10510,10500,to_date('18-APR-15','DD-MON-RR'),to_date('20-APR-15','DD-MON-RR'),8,16,8,'admin');

让我概述一下要求。

考虑 JobID = 10500

  • 按照sequenceid:10510,从4月18日开始,一直持续到4月20日。 成功完成后,它会获得与其对应的最小值、最大值、平均值作为摘要。

  • 然而,如果我们考虑序列 id: 10525,它从 22-apr 开始一直运行到 23-apr。 然而,由于一些网络中断,它在中间停止了几分钟并再次启动。 因为作业不完整,所以它的 min、max、avg 值为 NULL。 4 月 27 日又出现了另一个网络问题,因此它被停止并再次恢复。 最后在 4 月 27 日(序列 ID:10625)它成功完成,并为其分配了 min、max、avg 值。

在此处输入图片说明

在这种情况下,属于序列 ID 10625、10620 和 10525 的记录条目需要被视为单个组,序列 ID 10525 中的 start_ts 需要分配给序列 ID 10625,如下所示

在此处输入图片说明

上述情况的一个例外是,如果 end_ts 为空(序列 ID:10908)(它表示当前活动的作业)。

在此处输入图片说明

这里的分组应该是序列 id: 10825 并且输出应该像下面的截图。

在此处输入图片说明

如果您需要任何说明,请告诉我。

提前感谢您的时间和宝贵的建议。

尝试:

SELECT sequence_id, job_id, new_start_ts as start_ts, end_ts,
       minimum_value, maximum_value, average_value, userid
FROM (
    SELECT t.*,
           min( start_ts ) over ( partition by job_id, new_seq_id ) As new_start_ts
    FROM (
          SELECT t.* ,
                 first_value( case when minimum_value is not null then sequence_id end IGNORE NULLS )
                 over (partition by job_id order by sequence_id rows between current row and unbounded following ) as new_seq_id
          FROM SHIFT_LOG t
    ) t
)
WHERE minimum_value IS NOT NULL 
  OR new_seq_id IS NULL AND end_ts IS NULL
ORDER BY sequence_id desc;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM