Oracle
 sql >> Base de données >  >> RDS >> Oracle

Ajouter cumulativement les données manquantes du mois ou de l'année précédente

Une variante de l'approche @boneists, en commençant par vos exemples de données dans 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;

Ce qui donne également le même résultat, même s'il ne correspond pas non plus aux résultats attendus dans la question :

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

Le y CTE (n'hésitez pas à utiliser des noms plus significatifs !) génère toutes les années distinctes à partir de vos données d'origine, et ajoute également un classement, donc 2007 est 1, 2008 est 2, 2009 est 3 et 2016 est 4.

Le r Le CTE récursif combine vos données réelles avec des lignes fictives avec des ventes nulles, basées sur les données nom/mois des années précédentes.

À partir de ce que produit ce CTE récursif, vous pouvez faire votre somme cumulée analytique pour ajouter les soldes d'ouverture/de clôture. Cela utilise des clauses de fenêtrage pour décider quelles valeurs de vente inclure - essentiellement les soldes d'ouverture et de clôture sont la somme de toutes les valeurs jusqu'à ce point, mais l'ouverture n'inclut pas la ligne actuelle.