2013-08-12 2 views
0

이 같은 테이블에 상황을 가지고 :선택 롤링 개월 데이터

이 같은 출력 데이터의 3 롤링 개월을 선택하고 싶어 할
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 

:

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 개월 동안 동일한 작업 수행 방법.

%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

테이블에 키가있는 것이 좋습니다. –

+1

MySQL 또는 SAS/Proc Sql에서이 작업을 수행하고 있습니까, 아니면 신경 쓰지 않습니까? 첫 롤링 3 개월 동안 어떻게했는지 게시하십시오. – Joe

+0

데이터베이스는 MySQL이고 SAS/Proc Sql에서 사용합니다. 단 3 개월 동안 데이터를 작성하기 위해 다른 변수를 작성하고 마지막 달 값을 할당했습니다. –

답변

0

이 당신이 원하는 무엇인가 : 여기 은 적은 코드 걸리는 경우 나, SQL하여이 작업을 수행하려면, 기존의 SAS 코드?

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 "롤링"데이터를 포함한다.

+0

그것의 예기치 않은 결과를주는 .. 개월 1,2에 추가, 그래서 4 개월 동안 그것의 1,2,3,4,5,6 달 같은 데이터를 제공. 4 개월 에서처럼 3 개월 동안 2 회만 진행됩니다. 따라서 첫 3 개월 데이터를 하나 .. 다음 3 개월 데이터를 하나로 결합해야합니다. –

+0

@ munishbansal. . . 몇 달 동안 데이터를 원하지 않는다는 것을 어떻게 알 수 있습니까? 내가 말했듯이, 당신이 정말로 3, 4 개월 째의 데이터 만 원한다면,'clause'을 사용할 수 있습니다. –

+0

아닙니다. 제가 말하고자하는 바는 .. 1, 2, 3 개월의 데이터를 하나로 합쳐서 데이터 3 월을 말하고, 4 월에는 2,3,4의 데이터를 결합해야합니다. 는 4 월 –

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;