0

我在表中有这样的情况:

Month Product Score Visit_ID
1      A      2     113
1      B      3     114
2      A      4     115
3      C      5     116
3      D      6     118
4      E      7     119

我想选择 3 个滚动月份的数据并希望输出如下:

Month Product Score Visit_ID
3      A      2     113
3      B      3     114
3      A      4     115
3      C      5     116
3      D      6     118
4      A      4     115
4      C      5     116
4      D      6     118
4      E      7     119

我知道如何为第一个滚动 3 个月执行此操作,如何为多个滚动 3 个月执行相同操作。这是现有的 SAS 代码,如果需要更少的代码,我想通过 SQL 来执行此操作:

%macro Rolling_months(Initial_dataset=,Final_dataset=,mon_no=,rollmon_field=);
PROC SORT DATA=&Initial_dataset.;BY &DATERG;RUN;
DATA &Initial_dataset.1;
SET &Initial_dataset.;
BY &DATERG;
RETAIN CNT1 0;
IF FIRST.&DATERG THEN CNT1+1;
CALL SYMPUT('ROLL',CNT1);
RUN;
%put &roll;
PROC SORT DATA=&Initial_dataset.1 OUT=CAL(KEEP=&DATERG CNT1) NODUPKEY;BY &DATERG CNT1;RUN;
DATA TEMP(KEEP=X R);
st=&mon_no.;
st1=%eval(&mon_no.-1);
DO X=ST TO &roll.;
n=0; r=0;
 do n = 0 to st1;
   R=X-n;
 OUTPUT TEMP;
 end;
END;
RUN;
data roll(rename=(&daterg=rolling_months));
merge temp(in=a rename=(x=CNT1)) cal(in=b);
by CNT1;
if a and b;
run;
PROC SORT DATA=&Initial_dataset.1;BY CNT1;RUN;

proc sql;
create table &Final_dataset. AS
       (select 
          A.*,
          B.*

        FROM &Initial_dataset.1 A RIGHT JOIN ROLL B
            ON A.CNT1=B.R

);
quit;
4

2 回答 2

0

对 Gordon 的解决方案稍作修改,这可能就是您想要的。当您拥有大量数据时,我不确定性能。一个简单的数据步骤可能会更快。

proc sql;
 select month, product, score, visit_id
 from 
  (select month as month, product, score, visit_id 
   from t 
   union all
   select month+1 as month, product, score, visit_id 
   from t 
   union all
   select month+2 as month, product, score, visit_id
   from t
  ) s1
 inner join 
  (select min(month+2) as minmonth, max(month) as maxmonth 
   from t) s2
  on s1.month ge s2.minmonth and s1.month le s2.maxmonth
;
quit;
于 2013-08-14T13:42:09.210 回答
0

这是你想要的吗?

select month, product, score, visit_id
from t
union all
select month+1, product, score, visit_id
from t
union all
select month+2, product, score, visit_id
from t;

where这将包括第 1 个月和第 2 个月的“滚动”数据,您可以使用子句将其过滤掉。

于 2013-08-12T14:21:27.937 回答