sql >> Databasteknik >  >> RDS >> Oracle

Lägg till saknad data från föregående månad eller år kumulativt

En variant på @boneists tillvägagångssätt, som börjar med dina exempeldata i en 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;

Som får samma resultat också, även om det inte heller matchar de förväntade resultaten i frågan:

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

y CTE (använd gärna mer meningsfulla namn!) genererar alla distinkta år från dina ursprungliga data och lägger även till en rankning, så 2007 är 1, 2008 är 2, 2009 är 3 och 2016 är 4.

r rekursiv CTE kombinerar din faktiska data med dummy-rader med noll försäljning, baserat på namn/månadsdata från tidigare år.

Från vad den rekursiva CTE producerar kan du göra din analytiska kumulativa summa för att lägga till ingående/slutsaldo. Det här använder fönsterklausuler för att bestämma vilka försäljningsvärden som ska inkluderas - i huvudsak är öppnings- och utgående balanser summan av alla värden fram till denna punkt, men öppningen inkluderar inte den aktuella raden.



  1. En resa genom GIMR

  2. Vad är SQL Server?

  3. Välj COUNT(*) med DISTINCT

  4. Hur säkerhetskopierar man en postgresql-databas inifrån psql?