我从2013年1月开始为客户提供SAS库中的月度数据集,数据集名称为CUST_JAN2013,CUST_FEB2013 ........ CUST_OCT2017。这些客户数据集每月拥有200万会员的巨大记录。这个月度数据集有两列(客户编号和客户每月费用)。
我有一个输入数据集Cust_Expense,其中客户编号和月份为列。此Cust_Expense表只有250,000个成员,并希望通过加入客户编号从SPECIFIC月度SAS数据集中提取每个成员的费用数据。
Cust_Expense
------------
Customer_Number Month
111 FEB2014
987 APR2017
784 FEB2014
768 APR2017
.....
145 AUG2017
345 AUG2014
我尝试过使用call execute,但它尝试循环输入数据集的每个250,000条记录(Cust_Expense)并加入相应的每月SAS客户表,这需要花费太多时间。 有没有办法按月读取输入表(Cust_Expense),以便我们读取特定月份的所有客户,然后读取相同的每月表ONCE以从该月中提取所有记录,这样它就不会循环250,000次。 / p>
答案 0 :(得分:1)
根据您想要的结果,您可以通过每月过滤cust_expenses并加入相应的每月数据集来创建每月一个输出
%macro want;
proc sql noprint;
select distinct month
into :months separated by ' '
from cust_expenses
;
quit;
proc sql;
%do i=1 %to %sysfunc(countw(&months));
%let month=%scan(&months,&i,%str( ));
create table want_&month. as
select *
from cust_expense(where=(month="&month.")) t1
inner join cust_&month. t2
on t1.customer_number=t2.customer_number
;
%end;
quit;
%mend;
%want;
或者,您可以通过将所有这些月度数据集“联合”为一个并动态添加月份列来使用一个联接输出一个输出。
%macro want;
proc sql noprint;
select distinct month
into :months separated by ' '
from cust_expenses
;
quit;
proc sql;
create table want as
select *
from cust_expense t1
inner join (
%do i=1 %to %sysfunc(countw(&months));
%let month=%scan(&months,&i,%str( ));
%if &i>1 %then union;
select *, "&month." as month
from cust_&month
%end;
) t2
on t1.customer_number=t2.customer_number
and t1.month=t2.month
;
quit;
%mend;
%want;
在任何一种情况下,我都没有真正看到将这些月度数据集与cust_expense
数据集联系起来的重点。后者似乎没有保存月度数据集中尚未出现的任何信息。
答案 1 :(得分:1)
你的第一个,最好的答案是摆脱这些每月单独的表,并将它们放入一个ID和月份为关键的大表中。然后你可以简单地加入这个并继续前进。有这样的许多单独的表,其中数据元素确定他们所在的表是永远不是一个好主意。然后按月指数,使其更快。
如果你不能这样做,那么尝试创建一个所有这些表联合的视图。这样做可能会更快; SAS可能会决定实现视图,但可能不会(但如果它非常慢,那么请查看您的临时表空间,看看是否正在发生这种情况)。
然后第三个选项可能是使用SAS格式。使用CNTLIN option将较小的表格转换为格式。然后,单个大型datastep将允许您执行连接。
data want;
set jan feb mar apr ... ;
where put(id,CUSTEXPF1.) = '1';
run;
只有一次通过250k表,一次通过月表,加上非常快速的格式查找,这在数据步骤中无疑是零成本(因为磁盘i / o会慢一些)。
答案 2 :(得分:-1)
我猜您可以在特定数据集中输出数据,例如:
data test;
infile datalines dsd;
input ID : $2. MONTH $3. ;
datalines;
1,JAN
2,JAN
3,JAN
4,FEB
5,FEB
6,MAR
7,MAR
8,MAR
9,MAR
;
run;
data JAN FEB MAR;
set test;
if MONTH = "JAN" then output JAN;
if MONTH = "FEB" then output FEB;
if MONTH = "MAR" then output MAR;
run;
您将避免遍历所有ID(250000) 并且您将使用SAS的数据集声明
最后,您将获得包含相关ID的12 DATASET。
例如,如果您使用FEB2014,您将使用子字符串函数,数据集中的条件将变为:
...
set test;
...
if SUBSTR(MONTH,1,3)="FEB" then output FEB;
...
此致