SQL从事务表生成定期快照

SQL从事务表生成定期快照,sql,oracle,data-warehouse,Sql,Oracle,Data Warehouse,我试图在事后从数据库的事务表创建一个定期快照视图。事务表具有以下字段: 帐户id外键 事件id 状态 状态光盘 每次帐户在应用程序中更改状态时,都会向事务表中添加一个具有新状态的新行。我想生成一个视图,显示每个日期按状态列出的帐户数;它应具有以下字段: 快照 状态光盘 帐户的计数 这将获得任何给定日期的计数,但不是所有日期的计数: SELECT status_cd, COUNT(account_id) AS count_of_accounts FROM transactions JOIN (

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

帐户id外键 事件id 状态 状态光盘 每次帐户在应用程序中更改状态时,都会向事务表中添加一个具有新状态的新行。我想生成一个视图,显示每个日期按状态列出的帐户数;它应具有以下字段:

快照 状态光盘 帐户的计数 这将获得任何给定日期的计数,但不是所有日期的计数:

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

谢谢大家!

好吧,这很难解释

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

以该状态开始的客户数。 以该状态离开的客户数。 第一个值很简单。它只是按日期和状态对事务的聚合

第二个值几乎同样简单。您将获得以前的状态代码,并计算该状态代码在该日期离开的次数

然后,键是第一个值的累积和减去第二个值的累积和

我坦率地承认,如果您有SQL FIDLE,那么下面的代码没有经过测试,我很乐意对其进行测试。但结果查询是这样的:

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;

如果您有一个或多个状态没有更改的日期,并且希望在输出中包含这些状态,那么上面的查询将需要使用交叉连接来首先在结果集中创建行。目前尚不清楚这是否是一项要求,因此我将省略这一复杂情况。

您使用的是什么数据库?我猜是甲骨文,但你应该清楚地说出问题的标签。是的,甲骨文。谢谢你的提示!我发现将专有扩展从一个SQL转换到另一个SQL并不太难,但最好不用这样做。太棒了,非常感谢!您的代码中有一个输入错误,应该是prev\u status\u cd是**not**null,但除此之外,它工作得很好。我想要没有状态更改的日期快照。有没有比这更优雅的方法:选择不同的状态,状态cd,状态cd,状态cd上的SUMinc,状态cd上的PARTITION,状态cd上的ORDER,状态cd上的SUMdec,状态cd上的PARTITION,状态cd上的ORDEC,状态cd上的ORDER,状态cd上的ORDER,状态cd上的ORDER,状态cd上的ORDER,状态cd上的ORDEC,状态cd上的ORDER,状态cd上的DATAMOUNT,从选择状态cd,状态cd上选择状态cd,状态cd,状态cd,0作为dec_cnt从选择不同状态从事务交叉连接选择不同状态从事务联合所有。。。