Okej, det här kommer att bli svårt att förklara.
På varje datum för varje status bör du räkna upp två värden:
- Antalet kunder som börjar med den statusen.
- Antalet kunder som lämnar med den statusen.
Det första värdet är enkelt. Det är bara aggregeringen av transaktionerna efter datum och status.
Det andra värdet är nästan lika enkelt. Du får det föregående statuskod och räkna antalet gånger som den statuskoden "avgår" på det datumet.
Då är nyckeln den ackumulerade summan av det första värdet minus den ackumulerade summan av det andra värdet.
Jag erkänner fritt att följande kod inte är testad (om du hade en SQL Fiddle skulle jag gärna testa den). Men så här ser den resulterande frågan ut:
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;
Om du har datum där det inte finns någon förändring för en eller flera statusar och om du vill inkludera dessa i utdata, så skulle ovanstående fråga behöva använda cross join
för att först skapa raderna i resultatuppsättningen. Det är oklart om detta är ett krav, så jag utelämnar den komplikationen.