Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Fügen Sie fehlende Daten aus dem vorherigen Monat oder Jahr kumulativ hinzu

Eine Variation des @boneists-Ansatzes, beginnend mit Ihren Beispieldaten in einem CTE:

with t as (
  select 1 id, 'A' name, '2007' year, '04' month,  5 sales  from dual union all
  select 2 id, 'A' name, '2007' year, '05' month,  2 sales  from dual union all
  select 3 id, 'B' name, '2008' year, '12' month,  3 sales  from dual union all
  select 4 id, 'B' name, '2009' year, '12' month, 56 sales  from dual union all
  select 5 id, 'C' name, '2009' year, '08' month, 89 sales  from dual union all
  select 13 id,'B' name, '2016' year, '01' month, 10 sales  from dual union all
  select 14 id,'A' name, '2016' year, '02' month,  8 sales  from dual union all
  select 15 id,'D' name, '2016' year, '03' month, 12 sales  from dual union all
  select 16 id,'E' name, '2016' year, '04' month, 34 sales  from dual
),
y (year, rnk) as (
  select year, dense_rank() over (order by year)
  from (select distinct year from t)
),
r (name, year, month, sales, rnk) as (
  select t.name, t.year, t.month, t.sales, y.rnk
  from t
  join y on y.year = t.year
  union all
  select r.name, y.year, r.month, 0, y.rnk
  from y
  join r on r.rnk = y.rnk - 1
  where not exists (
    select 1 from t where t.year = y.year and t.month = r.month and t.name = r.name
  )
)
select name, year, month, sales,
  nvl(sum(sales) over (partition by name order by year, month
    rows between unbounded preceding and 1 preceding), 0) as opening_bal,
  nvl(sum(sales) over (partition by name order by year, month
    rows between unbounded preceding and current row), 0) as closing_bal
from r
order by year, month, name;

Was auch das gleiche Ergebnis liefert, obwohl es auch nicht mit den erwarteten Ergebnissen in der Frage übereinstimmt:

NAME YEAR MONTH      SALES OPENING_BAL CLOSING_BAL
---- ---- ----- ---------- ----------- -----------
A    2007 04             5           0           5
A    2007 05             2           5           7
A    2008 04             0           7           7
A    2008 05             0           7           7
B    2008 12             3           0           3
A    2009 04             0           7           7
A    2009 05             0           7           7
C    2009 08            89           0          89
B    2009 12            56           3          59
B    2016 01            10          59          69
A    2016 02             8           7          15
D    2016 03            12           0          12
A    2016 04             0          15          15
E    2016 04            34           0          34
A    2016 05             0          15          15
C    2016 08             0          89          89
B    2016 12             0          69          69

Das y CTE (Sie können gerne aussagekräftigere Namen verwenden!) generiert alle unterschiedlichen Jahre aus Ihren Originaldaten und fügt auch eine Rangfolge hinzu, sodass 2007 1, 2008 2, 2009 3 und 2016 4 ist.

Das r Der rekursive CTE kombiniert Ihre tatsächlichen Daten mit Dummy-Zeilen ohne Umsatz, basierend auf den Namens-/Monatsdaten aus früheren Jahren.

Aus dem, was dieser rekursive CTE erzeugt, können Sie Ihre analytische kumulative Summe erstellen, um die Eröffnungs-/Endsalden zu addieren. Dies verwendet Windowing-Klauseln, um zu entscheiden, welche Verkaufswerte eingeschlossen werden sollen - im Wesentlichen sind die Eröffnungs- und Schlusssalden die Summe aller Werte bis zu diesem Punkt, aber die Eröffnung beinhaltet nicht die aktuelle Zeile.