sql >> Base de Datos >  >> RDS >> Oracle

SQL para generar instantáneas periódicas de la tabla de transacciones

Bien, esto va a ser difícil de explicar.

En cada fecha para cada estado, debe contar dos valores:

  • La cantidad de clientes que comienzan con ese estado.
  • El número de clientes que se van con ese estado.

El primer valor es fácil. Es solo la agregación de las transacciones por fecha y estado.

El segundo valor es casi tan fácil. Obtienes el anterior código de estado y cuente la cantidad de veces que ese código de estado "sale" en esa fecha.

Entonces, la clave es la suma acumulada del primer valor menos la suma acumulada del segundo valor.

Admito libremente que el siguiente código no está probado (si tuviera un SQL Fiddle, me encantaría probarlo). Pero así es como se ve la consulta resultante:

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;

Si tiene fechas en las que no hay cambios para uno o más estados y desea incluirlos en la salida, entonces la consulta anterior debería usar cross join para crear primero las filas en el conjunto de resultados. No está claro si se trata de un requisito, así que dejo de lado esa complicación.