2014-06-25 128 views
0

我有一个课程项目数据,并且正在计算过去30天内每笔交易到此交易所花费的平均金额。平均每笔交易花费在此交易上的每月交易

例如,我在2014年6月24日发生了一笔交易,我希望在此交易之前查找过去30天内的账户总花费(24月24日24日),并将其除以在此时间段内的交易。我需要为每笔交易执行此操作。

数据的模样alltran:

obs tran_date tran_amt mechr_cate_cd 
1 05/04/14 5.32  4633 
2 05/06/14 8.97  5846 
3 06/02/14 10.13  7996 

我想输出看起来像

obs tran_date tran_amt mechr_cate_cd avg_amt30 
1 05/04/14 5.32  4633   5.32 
2 05/06/14 8.97  5846   7.15 
3 06/02/14 10.13  7996   8.14 

我想在PROC SQL中使用相关子查询:

proc sql; 
create table sub as 
select tran_date tran_amt 
from alltran; 
run; 

proc sql; 
select * from alltran a 
     where exists 
        (select avg(tran_amt) as avg_amt30 from sub b 
       where a.tran_date-30<=b.tran_date<=a.tran_date); 
run; 

我还没有机会测试它,但这是我的想法,非常感谢你!

+4

当然有办法做到这一点,但你应该先向我们展示你自己到底是什么,以便你可以从那里引导。堆栈溢出不是按需服务的代码;我们会帮助您处理您的代码,而不是为您写信。请阅读[帮助],[mcve](http://stackoverflow.com/help/mcve) – indivisible

+0

如果您即将使用,请不要将代码粘贴到评论部分,只需使用新信息编辑原始问题即可。 (并记住在所有行之前加上4个空格或突出显示粘贴的代码并点击格式化按钮) – indivisible

回答

0

所以有很多不同的方式可以处理这个问题,但我喜欢你要使用proc SQL的地方。我认为连接比“存在”更容易阅读,所以这就是我在示例中使用的。

data alltran; 
     infile datalines ; 
     input obs tran_date tran_amt mechr_cate_cd; 
     informat tran_date mmddyy10.; format tran_date mmddyy10.; 
     datalines ; 
     1 05/04/14 5.32  4633 
     2 05/06/14 8.97  5846 
     3 06/02/14 10.13  7996 
     ; 
    run; 

proc sql; 
    create table alltran_duped as 
    Select a.* , b.tran_amt as Cumulative_tran_amt 
    from alltran a 
     left join alltran b 
      on b.tran_date <= a.tran_date <= b.tran_date + 30; 

    create table alltran2 as 
    select obs, tran_date, tran_amt, mechr_cate_cd, avg(Cumulative_tran_amt) as avg_amt30 
    from alltran_duped 
    group by obs, tran_date, tran_amt, mechr_cate_cd; 
quit; 

上面PROC SQL步骤执行以下步骤: 1)左加入数据回本身,其中从连接表中的tran_date是从原来的记录30个或更少天。如果在前30天内有多个记录,记录将被复制。

2)将原始4列分组,并取第1步加入的平均tran_amt值。这一切都可以一步完成,但我认为将其分开可使代码更易于阅读。

还有其他方法可以解决这个问题,但我个人认为使用proc sql更简单,更容易检查(特别是如果您的代码由其他SQL用户审核)。

希望这会有所帮助!

+0

嗨,Acie,非常感谢你的帮助,它完美的工作! – JImmy