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

SQL per generare snapshot periodici dalla tabella delle transazioni

Ok, sarà difficile da spiegare.

In ogni data per ogni stato, dovresti contare due valori:

  • Il numero di clienti che iniziano con quello stato.
  • Il numero di clienti che escono con quello stato.

Il primo valore è facile. È solo l'aggregazione delle transazioni per data e stato.

Il secondo valore è quasi altrettanto facile. Ottieni il precedente codice di stato e contare il numero di volte che quel codice di stato "lascia" in quella data.

Quindi, la chiave è la somma cumulativa del primo valore meno la somma cumulativa del secondo valore.

Ammetto liberamente che il codice seguente non è stato testato (se avessi un SQL Fiddle, sarei felice di testarlo). Ma ecco come appare la query risultante:

select status_dte, status_cd,
       (sum(inc_cnt) over (partition by status_cd order by status_dt) -
        sum(dec_cnt) over (partition by status_cd order by status_dt)
       ) as dateamount
from ((select t.status_dt, t.status_cd, count(*) as inc_cnt, 0 as dec_cnt
       from transactions t
       group by t.status_dt, t.status_cd 
      ) union all
      (select t.status_dt, prev_status_cd, 0, count(*)
       from (select t.*
                    lag(t.status_cd) over (partition by t.account_id order by status_dt) as prev_status_cd
             from transactions t
            ) t
       where prev_status_cd is null
       group by t.status_dt, prev_status_cd
      ) 
     ) t;

Se hai date in cui non ci sono modifiche per uno o più stati e vuoi includerli nell'output, quindi la query precedente dovrebbe utilizzare cross join per creare prima le righe nel set di risultati. Non è chiaro se questo sia un requisito, quindi tralascio questa complicazione.