sql >> Databáze >  >> RDS >> Oracle

Kumulativně přidejte chybějící data z předchozího měsíce nebo roku

Variace na přístup @boneists, počínaje vašimi ukázkovými daty v 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;

Což také dostane stejný výsledek, i když to také neodpovídá očekávaným výsledkům v otázce:

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 (klidně použijte smysluplnější názvy!) generuje všechny odlišné roky z vašich původních dat a také přidává hodnocení, takže rok 2007 je 1, 2008 je 2, 2009 je 3 a 2016 je 4.

r rekurzivní CTE kombinuje vaše skutečná data s fiktivními řádky s nulovým prodejem na základě údajů o názvu/měsíci z předchozích let.

Z toho, co tento rekurzivní CTE produkuje, můžete provést svůj analytický kumulativní součet a přidat počáteční/konečné zůstatky. To využívá klauzule okénka k rozhodnutí, které hodnoty prodeje zahrnout - v podstatě počáteční a konečné zůstatky jsou součtem všech hodnot až do tohoto bodu, ale otevření nezahrnuje aktuální řádek.



  1. Jaký je ekvivalent dotazu MySQL k PHP strip_tags?

  2. Jak upravit soubor MySQL my.cnf

  3. Co je Undo and Redo v databázi Oracle

  4. Odstraňte duplicitní řádky na serveru SQL Server