Oké, dit wordt moeilijk uit te leggen.
Op elke datum voor elke status moet u twee waarden optellen:
- Het aantal klanten dat met die status begint.
- Het aantal klanten dat met die status vertrekt.
De eerste waarde is eenvoudig. Het is gewoon de aggregatie van de transacties op datum en status.
De tweede waarde is bijna net zo eenvoudig. Je krijgt de vorige statuscode en tel het aantal keren dat die statuscode op die datum "vertrekt".
De sleutel is dan de cumulatieve som van de eerste waarde minus de cumulatieve som van de tweede waarde.
Ik geef vrijelijk toe dat de volgende code niet is getest (als u een SQL Fiddle had, zou ik deze graag testen). Maar zo ziet de resulterende zoekopdracht eruit:
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;
Als u datums heeft waarop er geen verandering is voor een of meer statussen en u deze in de uitvoer wilt opnemen, dan zou de bovenstaande query cross join
moeten gebruiken om eerst de rijen in de resultatenset te maken. Het is onduidelijk of dit een vereiste is, dus ik laat die complicatie weg.