2013-09-21 8 views
5

ich eine Auswahl in Oracle erstellt, die die Anzahl der Übernachtungen pro Monat (falls vorhanden) für die Flugbesatzung zurückgibt:Gruppe von 3-Monats-Zeitraum

CRE_ALPHA CRE_NAME MONTH YEAR NIGHT_STOPS 
---------- --------- ------ ----- ------------ 
AAC  Adinda 6  2013 8 
AAC  Adinda 7  2013 9 
AAC  Adinda 8  2013 2 
AAC  Adinda 9  2013 7 
AAC  Adinda 10  2013 4 
CCU  Cristiano 6  2013 5 
CCU  Cristiano 7  2013 6 
CCU  Cristiano 8  2013 3 
CCU  Cristiano 9  2013 11 
CVA  Carine 7  2013 9 
CVA  Carine 9  2013 10 
CVA  Carine 10  2013 10 
Jetzt

, gibt es eine Grenze von 18 Nacht stoppt auf eine 3-Monats-Basis. Also würde ich gerne nach 3 aufeinanderfolgenden Monaten mit> 18 Nachtaufenthalten gruppieren. Das Ergebnis sollte wie folgt sein:

CRE_ALPHA CRE_NAME TIMESPAN  NIGHT_STOPS 
---------- --------- --------------- ------------ 
AAC  Adinda 6/2013-8/2013 19 
AAC  Adinda 7/2013-9/2013 18 
CCU  Cristiano 7/2013-9/2013 20 
CVA  Carine 7/2013-9/2013 19 
CVA  Carine 8/2013-10/2013 20 

Beachten Sie, dass, wenn es Null Nacht für einen Monat anhält, gibt es keine Reihe, aber ich würde mit 0

ein Ergebnis für 3 Monate, einschließlich den man gerne

Kann jemand helfen?

Wenn es helfen kann, wählen Sie die voll unter:


ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MM-YYYY hh24:mi:ss'; 
SELECT cre_id, cre_alpha, cre_first_name, cre_last_name, Maand, Jaar, count(*) "Night stops" 
FROM 
    (SELECT cre_id, cre_alpha, cre_first_name, cre_last_name, pos_crb_iata_code, dst, det, dsa, (dst - Prev_end_time) * 1440 stop_over, EXTRACT(MONTH FROM dst) Maand, EXTRACT(YEAR FROM dst) Jaar 
    FROM 
    (SELECT cre_id, cre_alpha, cre_first_name, cre_last_name, pos_crb_iata_code, dst, dsa, det, dea, LAG(det) OVER (ORDER BY cre_alpha, dst) Prev_end_time 
    FROM 
     (SELECT cre_id, cre_alpha, cre_first_name, cre_last_name, pos_crb_iata_code, 
     COALESCE(flt_mvt_db, flt_com_dep_blk, pog_std, gco_start, oth_std, rsv_std) as dst, 
     COALESCE(flt_mvt_ab, flt_com_arr_blk, pog_sta, gco_end, oth_sta, rsv_sta) as det, 
     COALESCE(flt_apt_iata_code_dep, pog_apt_iata_code_from, gco_apt_iata_code, rsv_apt_iata_code) as dsa, 
     COALESCE(flt_apt_iata_code_arr, pog_apt_iata_code_to, gco_apt_iata_code, rsv_apt_iata_code) as dea 
     FROM 
     (SELECT DISTINCT cre_id, cre_alpha, cre_first_name, cre_last_name, pos_crb_iata_code 
     FROM master.crews, master.assignments, master.positions 
     WHERE asg_pos_id = pos_id AND asg_cre_id = cre_id AND asg_d_type <> 'LEA' 
     AND asg_start_time BETWEEN '01-JUN-2013' AND '01-NOV-2013' 
     ORDER BY cre_alpha) tab1, master.assignments 
     FULL OUTER JOIN master.flights ON master.assignments.asg_flt_id = master.flights.flt_id 
     FULL OUTER JOIN master.positionings ON master.assignments.asg_pog_id = master.positionings.pog_id 
     FULL OUTER JOIN master.ground_courses ON master.assignments.asg_gco_id = master.ground_courses.gco_id 
     FULL OUTER JOIN master.other_duties ON master.assignments.asg_oth_id = master.other_duties.oth_id 
     FULL OUTER JOIN master.reserves ON master.assignments.asg_rsv_id = master.reserves.rsv_id 
     WHERE asg_d_type <> 'LEA' AND asg_d_type <> 'STP' AND asg_cre_id = tab1.cre_id 
     AND asg_start_time BETWEEN '01-JUN-2013' AND '02-NOV-2013' AND asg_actif = 'Y' 
     ORDER BY cre_alpha, asg_start_time) 
    ) 
    WHERE pos_crb_iata_code <> dsa 
    AND EXTRACT(DAY FROM dst) - EXTRACT(DAY FROM Prev_end_time) >= 1) 
WHERE stop_over > 240 
GROUP BY cre_id, cre_alpha, cre_first_name, cre_last_name, Maand, Jaar 
ORDER BY cre_alpha; 

Antwort

3

Sie analytische Funktionen verwenden können, um zu erreichen, was Sie wollen. Aufbauend auf Ihre aktuelle Abfrage, geht es wie folgt aus:

select * 
from (
    select cre_alpha, cre_name, 
    month month_end, year year_end, 
    sum(night_stops) over (
     partition by cre_alpha, cre_name 
     order by year * 12 + month 
     range between 2 preceding and current row 
    ) as night_stops 
    from (
     ... your current query ... 
    ) t 
) m 
where night_stops >= 18 

Hinweis:

  • Die Abfrage gibt das Ende (Jahr/Monat) der Zeitraum von 3 Monaten. Sie müssen es verlängern, um auch den Beginn der Periode zu drucken.
  • Ich habe die Bedingung >= 18 verwendet, um Ihre Ausgabe zu entsprechen, obwohl der Text sagt, es ist > 18.
  • Die Windowing-Klausel range between 2 preceding and current row zusammen mit der Reihenfolge von Klausel year * 12 + month stellen Sie sicher, dass ein dreimonatiges Fenster genommen wird und nicht nur drei aufeinanderfolgende Zeilen. Dies ist relevant, wenn in Ihrer Basisabfrage ein Monat fehlt.

Viel Spaß.

+0

Wie unterscheidet sich die Bestellung nach "Jahr * 12 + Monat" von der Bestellung nach "Monat"? "Stellen Sie sicher, dass ein dreimonatiges Fenster und nicht nur drei aufeinander folgende Reihen genommen werden. Wie kommt es? –

+0

Wenn alle Zeilen aus demselben Jahr stammen, können Sie "Monat" nur anstelle von "Jahr * 12 + Monat" verwenden. Aber wenn sie aus verschiedenen Jahren stammen, dann ist es wichtig, dass z.B. Dezember 2012 und Januar 2013 sind fortlaufende Nummern zugewiesen, so dass Sie die Windowing-Klausel richtig anwenden können. – Codo

+0

Aha! Dann macht es Sinn. –