选择滚动月份数据

时间:2013-08-12 14:03:37

标签: mysql sql sas

我有这样的情况:

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;

2 个答案:

答案 0 :(得分: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;

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

答案 1 :(得分:0)

对戈登的解决方案进行一些小修改,这可能就是你想要的。当你有大量数据时,我不确定性能。简单的数据步骤可能会更快。

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;