2017-12-20 2 views
1

Ich habe einen Datensatz:wie Summe über Zeilen in einer Gruppe unter der Bedingung in Oracle basiert bekommen

type    month  id1 id2 id3 value 
history   jan-17  1 2 3  10 
future   jan-17  1 2 3  15 
history   feb   1 2 3  12 
history   march  1 2 3  11 
future   march  1 2 3  14 

Ich möchte für jeden Monat auf einige Berechnung auf der Grundlage Wert erhalten und auf den Wert der type Spalte basiert.

Für zB: die Ausgabe sollte wie folgt aussehen:

month id1 id2 id3 value 
JAN-17 1 2 3  15(future value of jan) + 0(as future value of feb is not present)+ 14(take the future value of march) 
FEB-17 1 2 3  10(history value of jan)+14(take the future value of march) 
MAR-17 1 2 3  10(history value of jan)+12(history value of feb)+11(history value of mar) 

Die Berechnung basiert auf der Anzahl Quartal eines jeden Monats in einem Jahr basiert.
Wenn es im ersten Monat eines Quartals ist, nehmen Sie den zukünftigen Wert ersten Monat + Zukunft des zweiten Monats + zukünftigen Wert 3. Monat

Wenn der Monat 2. Monat eines Quartals ist, nehmen Sie die Geschichte Wert von 1. Monat + zukünftiger Wert des zweiten Monats + zukünftiger Wert des dritten Monats

Wenn der Monat der dritte Monat eines Quartals ist, nehmen Sie den historischen Wert des ersten Monats + historischen Werts des zweiten Monats + zukünftigen Werts des dritten Monats.

Ich habe versucht Partitionierung der Datenmenge basierend auf Monat id1, id2, id3, aber es gibt mir nicht das erwartete Ergebnis.

Antwort

0

Ihre gewünschte Ausgangs die Regeln widersprechen, die Sie weiter schrieb:

Wenn es im ersten Monat eines Quartals ist, nehmen Sie den zukünftigen Wert ersten Monat + Zukunft des zweiten Monats + zukünftigen Wert 3. Monat

Wenn der Monat 2. Monat eines Quartals ist, nehmen Sie die Geschichte Wert von 1. Monat + zukünftigen Wert von 2. Monat + zukünftigen Wert 3. Monat

Wenn der Monat 3. Monat eines Quartals ist, nehmen Sie die Geschichte Wert 1. Monat + historischer Wert 2. Monat + zukünftiger Wert 3. Monat th

ich diese Regeln umgesetzt werden, weil sie klare Logik und sind einfacher zu implementieren:

with t1 as (select 'history' type from dual union all select 'future' type from dual), 
    d as (select add_months(date '2017-01-01', rownum - 1) month, 1 id1, 2 id2, 3 id3 from dual connect by level < 4), 
    t2 as (select * from t1, d), 
    source (type, month, id1, id2, id3, value) as (
      select 'history', 'jan-17', 1, 2, 3, 10 from dual union all 
      select 'future', 'jan-17', 1, 2, 3, 15 from dual union all 
      select 'history', 'feb-17', 1, 2, 3, 12 from dual union all 
      select 'history', 'mar-17', 1, 2, 3, 11 from dual union all 
      select 'future', 'mar-17', 1, 2, 3, 14 from dual) 
select to_char(month, 'mon-yy') mon, id1, id2, id3, history, future, 
     sum(history) over (partition by to_char(month, 'Q') order by month) - history + 
     sum(future) over (partition by to_char(month, 'Q') order by month desc) value 
    from (select t2.type, t2.month, nvl(s.id1, t2.id1) id1, nvl(s.id2, t2.id2) id2, nvl(s.id3, t2.id3) id3, nvl(value, 0) value 
      from t2 left join source s on s.type = t2.type and s.month = to_char(t2.month, 'mon-yy')) 
pivot (sum(value) for type in ('history' history, 'future' future)) 
order by month 

Wie es funktioniert:

  • Subqueries t1, t2 und d werden verwendet, um Erstellen Sie eine vollständige Liste der Monate und Typen
  • dann verbinden Sie sie mit Quelldaten und machen einen Drehpunkt
  • berechnen von „Futures“ und „Geschichten“ in verschiedene Richtungen
  • dann kombinieren diese laufenden Summen zusammen minus aktuelle Geschichte Wert, laufende Summe, was gibt uns genau das, was wir brauchen:

    MON     ID1  ID2  ID3 HISTORY  FUTURE  VALUE 
    ------------ ---------- ---------- ---------- ---------- ---------- ---------- 
    jan-17    1   2   3   10   15   29 
    feb-17    1   2   3   12   0   24 
    mar-17    1   2   3   11   14   36 
    

Diese Lösung kann für jeden Zeitraum angewendet werden, Daten werden für jedes Quartal separat berechnet.

0

Ich habe keine Ahnung, was ich mit ID1, ID2, ID3 tun soll, also wähle ich es zu ignorieren, besser erklären Sie die entsprechende Logik dafür.Wird es immer denselben Wert für Geschichte, Zukunft eines bestimmten Monats geben?

with 
x as 
    (select 'hist' type, To_Date('JAN-2017','MON-YYYY') ym , 10 value from dual union all 
    select 'future' type, To_Date('JAN-2017','MON-YYYY'), 15 value from dual union all 
    select 'future' type, To_Date('FEB-2017','MON-YYYY'), 1 value from dual), 
y as 
    (select * from x Pivot(Sum(Value) For Type in ('hist' as h,'future' as f))), 
    /* Pivot for easy lag,lead query instead of working with rows..*/ 
z as 
    (
     select ym,sum(h) H,sum(f) F from (
      Select y.ym,y.H,y.F from y 
      union all 
      select add_months(to_Date('01-JAN-2017','DD-MON-YYYY'),rownum-1) ym, 0 H, 0 F 
      from dual connect by rownum <=3 /* depends on how many months you are querying... 
      so this dual adds the corresponding missing 0 records...*/ 
     ) group by ym 
    ) 
select 
ym, 
Case 
    When MOD(Extract(Month from YM),3) = 1 
    Then F + Lead(F,1) Over(Order by ym) + Lead(F,2) Over(Order by ym) 
    When MOD(Extract(Month from YM),3) = 2 
    Then Lag(H,1) Over(Order by ym) + F + Lead(F,1) Over(Order by ym) 
    When MOD(Extract(Month from YM),3) = 3 
    Then Lag(H,2) Over(Order by ym) + Lag(H,1) Over(Order by ym) + F 
End Required_Value 
from z 
Verwandte Themen