sql >> Base de Datos >  >> RDS >> Oracle

Agregue los datos faltantes del mes o año anterior de forma acumulativa

Una variación del enfoque de @boneists, comenzando con sus datos de muestra en un 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;

Que también obtiene el mismo resultado, aunque tampoco coincide con los resultados esperados en la pregunta:

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

El y CTE (¡no dude en usar nombres más significativos!) genera todos los años distintos a partir de sus datos originales y también agrega una clasificación, por lo que 2007 es 1, 2008 es 2, 2009 es 3 y 2016 es 4.

El r El CTE recursivo combina sus datos reales con filas ficticias con cero ventas, según los datos de nombre/mes de años anteriores.

A partir de lo que produce ese CTE recursivo, puede hacer su suma acumulativa analítica para agregar los saldos de apertura/cierre. Se utilizan cláusulas de ventana para decidir qué valores de venta incluir; esencialmente, los saldos de apertura y cierre son la suma de todos los valores hasta este punto, pero la apertura no incluye la fila actual.