sql >> Database teknologi >  >> RDS >> Oracle

Tilføj manglende data fra forrige måned eller år kumulativt

En variation af @boneists tilgang, der starter med dine prøvedata 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 også får det samme resultat, selvom det heller ikke matcher de forventede resultater i spørgsmålet:

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 (brug gerne mere meningsfulde navne!) genererer alle de forskellige år fra dine originale data og tilføjer også en rangering, så 2007 er 1, 2008 er 2, 2009 er 3, og 2016 er 4.

r rekursiv CTE kombinerer dine faktiske data med dummy-rækker med nul salg, baseret på navn/månedsdata fra tidligere år.

Ud fra, hvad den rekursive CTE producerer, kan du gøre din analytiske kumulative sum for at tilføje åbnings-/slutsaldi. Dette bruger vinduesklausuler til at beslutte, hvilke salgsværdier der skal inkluderes - i det væsentlige er åbnings- og slutsaldi summen af ​​alle værdier indtil dette punkt, men åbning inkluderer ikke den aktuelle række.



  1. PostgreSQL brugergruppe NL

  2. Grænse for tilstanden WHERE col IN (...).

  3. Hvordan kontrollerer man SQL Server-databasekompatibilitet efter sp_dbcmptlevel er forældet?

  4. Sådan ændres dato- og tidsformater i T-SQL