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.