2016-04-03 13 views
2

Kann jemand mit Ideen helfen, die Anforderungen unten beschriebenen Umsetzung:Oracle SQL-Abfrage Logik - Gruppe durch, basierend auf Datum Difference

enter image description here

Tabelle oben (siehe Screenshot) hält die Job-Historie der geplanten Prozesse.

Meine Anforderung ist es, eine Zieltabelle zu haben, die den kumulativen Verlauf gemäß dem folgenden Screenshot verwaltet.

enter image description here

Siehe unten für Quell-/Zieltabellenstruktur und Quelle Beispieldatensätze SQL-Code:

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'); 

Lassen Sie mich einen Überblick über die Anforderung geben.

Betrachten JobID = 10500

  • Per sequenceid: 10510, hat es bei 18-April gestartet und lief bis 20 April Sobald es erfolgreich abgeschlossen wurde, erhält es den Wert min, max, avg als Zusammenfassung.

  • Wenn wir jedoch Sequenz-ID: 10525 betrachten, begann es von 22-April und lief bis 23-Apr. Aufgrund eines Netzwerkausfalls blieb es jedoch für einige Minuten in der Mitte stehen und startete erneut. Aus diesem Grund hat es min, max, avg value als NULL, da der Job unvollständig ist. Erneut hatte es am 27. April ein weiteres Netzwerkproblem, so dass es gestoppt und wieder fortgesetzt wurde. Schließlich am 27. April (Sequenz-ID: 10625) wurde es erfolgreich abgeschlossen und ihm wurde der Wert min, max, avg zugewiesen.

enter image description here

In dieser Fall Satzeingaben, die zu Sequenz von id 10625, 10620 und 10525 Bedürfnissen als einzelne Gruppe und start_ts von Sequenz-ID 10525 Bedürfnissen in Betracht gezogen werden, um sequenceid 10625 zugewiesen zu bekommen, wie unten

enter image description here

Eine Ausnahme obigen Fall ist, wenn end_ts null ist (Sequenz ID: 10908) (derzeit aktiven Auftrag bezeichnet).

enter image description here

Hier Gruppierung mit Sequenz-ID sein sollte: 10825 und Ausgabe wie wie unten Screenshot sein sollte.

enter image description here

Lassen Sie mich wissen, wenn Sie irgendwelche Erklärungen benötigen.

Vielen Dank im Voraus für Ihre Zeit und wertvolle Anregungen.

Antwort

2

Versuchen:

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

Könnten Sie bitte die Reihenfolge der Ausführung von logischen Operatoren in sagen, wo ist es wie 1) '(MINIMUM_VALUE IS NOT NULL OR new_seq_id IS NULL) UND end_ts IS NULL' oder 2) 'minimum_value IST NICHT NULL OR (new_seq_id IST NULL UND end_ts IST NULL)'. Ich meine was zuerst ausgewertet wird. –

+0

@sql_dummy Der SQL-Standard definiert nicht die Reihenfolge der Auswertung der Bedingung 'x OR y AND z', im Gegensatz zu beispielsweise Java, C++. Die Datenbank ist frei, irgendeine Reihenfolge der Bewertung zu wählen, die thiks besser ist. SQL ist eine deklarative Sprache - ich interessiere mich nicht für die Reihenfolge der Auswertung, ich erkläre nur: "gib mir Zeilen, für die die Bedingung' x ODER y UND z 'wahr ist " – krokodilko

+0

aber wird das nicht das Ergebnis ändern? Angenommen, 'x ist wahr, y ist falsch, z ist falsch' in 'case1', wo die Bedingung falsch zurückgibt und in 'case2' wird die Bedingung wahr –

Verwandte Themen