在 SAS 中查找第二个最晚日期
Posted
技术标签:
【中文标题】在 SAS 中查找第二个最晚日期【英文标题】:Finding the second latest date in SAS 【发布时间】:2015-11-20 00:43:56 【问题描述】:我有两列:
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;
【讨论】:
嗨,对不起,我认为我的问题不清楚。我现在改写了。我想要的是帐号以及他们的第二次最新交易。所以,基本上,我的新数据集应该有大约 97k 条记录。当我尝试上面的代码时,我得到了 130 万条记录。【参考方案2】:您的查询(除了格式)看起来很合理。我想知道子查询中的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)
上建立索引。数据步骤解决方案(在另一个答案中提出)可能会快得多。
【讨论】:
【参考方案3】: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;
【讨论】:
【参考方案4】: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 是最终的数据集
【讨论】:
【参考方案5】:您可以使用retain
一次性遍历数据:
T1
是最新的 TRANS_DATE,T2
是之前的。
【讨论】:
以上是关于在 SAS 中查找第二个最晚日期的主要内容,如果未能解决你的问题,请参考以下文章
查找每个 ID 的特定日期之前的最大日期和特定日期之后的最小日期 [关闭]