Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

SQL para gerar instantâneos periódicos da tabela de transações


Ok, isso vai ser difícil de explicar.

Em cada data para cada status, você deve contar dois valores:
  • O número de clientes que começam com esse status.
  • O número de clientes que saem com esse status.

O primeiro valor é fácil. É apenas a agregação das transações pela data e pelo status.

O segundo valor é quase tão fácil. Você obtém o anterior código de status e conte o número de vezes que esse código de status "sai" naquela data.

Então, a chave é a soma cumulativa do primeiro valor menos a soma cumulativa do segundo valor.

Admito livremente que o código a seguir não foi testado (se você tivesse um SQL Fiddle, ficaria feliz em testá-lo). Mas é assim que a consulta resultante se parece:
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;

Se você tiver datas em que não há alteração para um ou mais status e você deseja incluí-los na saída, a consulta acima precisaria usar cross join para primeiro criar as linhas no conjunto de resultados. Não está claro se isso é um requisito, então estou deixando de fora essa complicação.