Dobře, tohle bude těžké vysvětlit.
Ke každému datu pro každý stav byste měli spočítat dvě hodnoty:
- Počet zákazníků, kteří začínají s tímto stavem.
- Počet zákazníků, kteří odejdou s tímto stavem.
První hodnota je snadná. Jde pouze o agregaci transakcí podle data a stavu.
Druhá hodnota je téměř stejně snadná. Získáte předchozí stavový kód a spočítat, kolikrát tento stavový kód k danému datu „opustí“.
Potom je klíčem kumulativní součet první hodnoty mínus kumulativní součet druhé hodnoty.
Klidně přiznávám, že následující kód není testován (pokud byste měli SQL Fiddle, rád ho otestuji). Ale takto vypadá výsledný dotaz:
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;
Pokud máte data, u kterých nedošlo ke změně jednoho nebo více stavů a chcete zahrnout do výstupu, pak by výše uvedený dotaz musel použít cross join
nejprve vytvořit řádky v sadě výsledků. Není jasné, zda je to požadavek, takže tuto komplikaci vynechávám.