2016-04-03 69 views
2

有人可以帮助实现下述要求的想法:的Oracle SQL查询逻辑 - 集团基于日期的差异

enter image description here

表上方(截图)维护计划流程的工作历史。

我的要求是有一个目标表维护累积历史,如下图所示。

enter image description here

参阅以下源/目标表结构和源样本记录的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'); 

我举的要求的概述。

考虑作业ID = 10500

  • 按sequenceid:10510,它已开始在4月18日,跑至20 - 4月一旦成功完成,它将获得与其对应的最小,最大,平均值作为摘要。

  • 但是,如果我们考虑序列号:10525,它从22月开始,一直运行到23月。但由于网络中断,中途停止了几分钟,然后重新开始。因为它的min,max,avg值为NULL,因为作业是不完整的。它在27日再次发生了另一个网络问题,因此它被停止并再次恢复。最后在27日apr(序号:10625)成功完成,min,max,avg分配给它。

enter image description here

属于序列号的10625,10620和10525的需求这种情况下记录的条目被视为从序列编号10525层的需求单组和start_ts获得分配给sequenceid 10625如下

enter image description here

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

enter image description here

这里分组应该与序列ID:10825和输出应该像如下屏幕截图。

enter image description here

让我知道如果你需要任何澄清。

在此先感谢您的宝贵时间和宝贵建议。

回答

2

尝试:

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; 
+0

你能告诉逻辑运算符的执行在何处,是像1)为了'(MINIMUM_VALUE IS NOT NULL 或new_seq_id IS NULL)AND end_ts IS NULL'或者是它像2)'minimum_value IS NOT NULL OR(new_seq_id IS NULL AND end_ts IS NULL)'。我的意思是首先评估哪一个。 –

+0

@sql_dummy SQL标准没有定义条件'x OR y AND z'的评估顺序,与例如Java,C++相反。数据库可以自由选择任何评估顺序,但它更好。 SQL是声明性语言 - 我不关心评估的顺序,我只声明:“给我条件为'x OR y AND z'为真的行' – krokodilko

+0

但是这不会改变reult?假设'case1'中'x为true,y为false,z为false',where条件将返回false,'case2'条件将返回true –