2015-11-20 79 views
0

第二最新的日期我有两列:发现在SAS

GRP_ACCT_NO,TRANS_DATE

数据是关于由不同的账户进行的交易。因此,GRP_ACCT_NO具有周期性值,TRANS_DATE给出该特定账户进行交易的日期。我在数据集中有大约150万条记录,但只有97k个独特账户。我想找到每个帐户的第二最新交易日在SAS

这里是我试过的代码:

proc sql; 
    create table second_latest_trans as 
    select GRP_ACCT_NO,Max(TRANS_DATE) from project.spend as ps 
    where TRANS_DATE < (select max(TRANS_DATE) 
         from project.spend as ps2 
         where ps.GRP_ACCT_NO = ps2.GRP_ACCT_NO 
         group by GRP_ACCT_NO) 
    group by GRP_ACCT_NO; 
quit; 

的代码似乎并没有得到任何结果。它需要很长时间才能加载。

请帮忙!!

回答

1

SQL没有观察顺序的概念。使用DATA步骤。如果您的数据尚未排序,请对其进行排序(创建索引)。

如果你只是想第二个记录,即使有关系,那么你可以只计算每个帐户的记录。

data second_latest_trans; 
    set project.spend; 
    by GRP_ACCT_NO TRANS_DATE; 
    if first.grp_acct then recno=0; 
    recno+1; 
    if recno=2 then output; 
run; 

如果对于TRANS_DATE值相同的多个记录,并且希望TRANS_DATE的第二个不同的值,那么这更复杂的步骤会工作。

data second_latest_trans; 
    set project.spend; 
    by GRP_ACCT_NO TRANS_DATE; 
    if first.grp_acct then found=0; 
    else if not found and first.trans_date then do; 
    output; 
    found=1; 
    end; 
    retain found; 
run; 
+0

嗨,对不起,我认为我的问题不清楚。我现在已经改写了它。我想要的是帐号以及他们的第二次最新交易。所以,基本上,我的新数据集应该有大约97k条记录。当我尝试上述代码时,我获得了130万条记录。 – user3252148

1

您的查询(格式除外)看起来很合理。我想知道子查询中的group by是否正在抛弃。试试这个版本:

proc sql; 
create table second_latest_trans as 
    Select GRP_ACCT_NO, Max(TRANS_DATE) 
    from project.spend ps 
    where TRANS_DATE < (SELECT max(ps2.TRANS_DATE) 
         from project.spend ps2 
         where ps.GRP_ACCT_NO = ps2.GRP_ACCT_NO 
         ) 
    group by GRP_ACCT_NO; 
quit; 

如果你想这跑得更快,你要对project.spend(GRP_ACCT_NO, TRANS_DATE)的索引。数据步骤解决方案(在另一个答案中提出)可能会快得多。

0

SAS SQL不是处理序列问题的好工具。如果你想在组中找到第二个最高或最低的记录,也许你可以试试这个。我以班级为例,在每组中找到第二个体重的人。方法是首先从组中选出最大重量的人,然后选择最大重量的人,但是,它可以处理重量。希望给你一些想法。

proc sql; 
    select * from (select * from sashelp.class where weight not in 
    (select weight from sashelp.class group by age having weight=max(weight))) 
    group by age having weight=max(weight); 
quit; 
0
data test; 
set spend; 
run; 

排序acct_no所以最大的日期是在上面。

proc sort data=test; 
by grp_acct_no trans_date descending; 
run; 

删除对应于最新的日期

data test2; 
set test; 
by grp_acct_no trans_date; 
if first.grp_acct_no =1 and first.trans_date =1 then delete; 
run; 

现在对应于每个acct_no的第一个记录是因为最大的一个被移除的第二大日的结果。删除除此记录外的所有内容

data test3; 
set test2; 
by grp_acct_no trans_date; 
if Not (first.grp_acct_no =1 and first.trans_date =1) then delete; 

run; 

TEST3是最终的数据集

0

您可以使用retain在单次通过数据做到这一点:

 
data want ; 
    set have ; 
    by GRP_ACCT_NO TRANS_DATE ; 

    retain T1 T2 . ; 
    if first.GRP_ACCT_NO then call missing(T1,T2) ; 

    if TRANS_DATE > T1 then do ; 
    T2 = T1 ; 
    T1 = TRANS_DATE ; 
    end ; 

    if last.GRP_ACCT_NO ; 

    format T1 T2 date9. ; 
run ; 

T1是最新TRANS_DATE,T2是前一个那。