Oke, ini akan sulit dijelaskan.
Pada setiap tanggal untuk setiap status, Anda harus menghitung dua nilai:
- Jumlah pelanggan yang memulai dengan status tersebut.
- Jumlah pelanggan yang keluar dengan status tersebut.
Nilai pertama mudah. Ini hanya agregasi transaksi berdasarkan tanggal dan status.
Nilai kedua hampir sama mudahnya. Anda mendapatkan sebelumnya kode status dan hitung berapa kali kode status itu "ditinggalkan" pada tanggal tersebut.
Kemudian, kuncinya adalah jumlah kumulatif dari nilai pertama dikurangi jumlah kumulatif dari nilai kedua.
Saya dengan bebas mengakui bahwa kode berikut tidak diuji (jika Anda memiliki SQL Fiddle, saya akan dengan senang hati mengujinya). Tapi seperti inilah tampilan kueri yang dihasilkan:
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;
Jika Anda memiliki tanggal di mana tidak ada perubahan untuk satu atau lebih status dan Anda ingin memasukkannya ke dalam output, maka kueri di atas perlu menggunakan cross join
untuk terlebih dahulu membuat baris di set hasil. Tidak jelas apakah ini suatu persyaratan, jadi saya mengabaikan kerumitan itu.