Okay, det bliver svært at forklare.
På hver dato for hver status skal du tælle to værdier op:
- Antallet af kunder, der starter med denne status.
- Antallet af kunder, der forlader med denne status.
Den første værdi er nem. Det er blot aggregeringen af transaktionerne efter dato og status.
Den anden værdi er næsten lige så nem. Du får den forrige statuskode og tæl det antal gange, den statuskode "forlader" på den dato.
Derefter er nøglen den kumulative sum af den første værdi minus den kumulative sum af den anden værdi.
Jeg indrømmer frit, at følgende kode ikke er testet (hvis du havde en SQL Fiddle, ville jeg med glæde teste den). Men sådan ser den resulterende forespørgsel ud:
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;
Hvis du har datoer, hvor der ikke er nogen ændring for en eller flere statusser og du vil inkludere dem i outputtet, så skal ovenstående forespørgsel bruge cross join
for først at oprette rækkerne i resultatsættet. Det er uklart, om dette er et krav, så jeg udelader den komplikation.