SQL从事务表生成定期快照

时间:2014-12-06 01:42:18

标签: sql oracle data-warehouse

我试图在事后从数据库的事务表创建定期快照视图。事务表包含以下字段:

  • account_id(外键)
  • event_id的
  • status_dt
  • status_cd

每次帐户更改应用程序中的状态时,都会使用新状态将新行添加到事务表中。我想制作一个视图,按日期显示每个帐户的帐户数量;它应该包含以下字段:

  • snapshot_dt
  • status_cd
  • count_of_accounts

这将获得任何指定日期的计数,但不是所有日期的计数:

SELECT status_cd, COUNT(account_id) AS count_of_accounts
FROM transactions
JOIN (
      SELECT account_id, MAX(event_id) AS event_id
      FROM transactions
      WHERE status_dt <= DATE '2014-12-05') latest
USING (account_id, event_id)
GROUP BY status_cd

谢谢!

1 个答案:

答案 0 :(得分:0)

好的,这很难解释。

在每个状态的每个日期,您应该计算两个值:

  • 以该状态开头的客户数量。
  • 以该状态离开的客户数量。

第一个值很简单。它只是按日期和状态汇总的交易。

第二个值几乎一样容易。您将获得之前的状态代码,并计算该状态代码&#34;离开&#34;的次数。在那一天。

然后,密钥是第一个值减去第二个值的累积和的累积和。

我承认以下代码未经过测试(如果你有一个SQL小提琴,我很乐意测试它)。但这就是生成的查询的样子:

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;

如果你有一个或多个状态没有变化的日期,你想在输出中包含那些,那么上面的查询需要使用cross join来创建结果集中的行。目前还不清楚这是否是一项要求,所以我要忽略这种并发症。