Well, its not pretty, but gives a result: data subscriptions; infile datalines; format date_from date_to format=date9.; input @01 id 1. @03 magazine $4. @08 date_from date9. @18 date_to date9.; datalines; 1 mag1 01jan2014 15mar2014 1 mag2 20feb2014 12apr2014 1 mag3 20feb2014 12apr2014 1 mag4 25mar2014 16may2014 2 mag1 01jan2014 01jul2014 2 mag2 01feb2014 01apr2014 ; run; proc sql noprint; select min(date_from) into :min_date from WORK.SUBSCRIPTIONS; select max(date_to) into :max_date from WORK.SUBSCRIPTIONS; quit; data template (keep=id days); attrib id format=best. days format=date9.; do j=1 to 2; do i=&min_date. to &max_date.; id=j; days=i; output; end; end; run; data have; set subscriptions; attrib days format=date9.; do i=date_from to date_to; days=i; output; end; run; proc sql; create table working as select TEMP.ID, TEMP.DAYS, catx('/',A.MAGAZINE,B.MAGAZINE,C.MAGAZINE,D.MAGAZINE) as MAG from TEMPLATE TEMP left join (select * from HAVE where MAGAZINE="mag1") A on TEMP.ID=A.ID and TEMP.DAYS=A.DAYS left join (select * from HAVE where MAGAZINE="mag2") B on TEMP.ID=B.ID and TEMP.DAYS=B.DAYS left join (select * from HAVE where MAGAZINE="mag3") C on TEMP.ID=C.ID and TEMP.DAYS=C.DAYS left join (select * from HAVE where MAGAZINE="mag4") D on TEMP.ID=D.ID and TEMP.DAYS=D.DAYS; quit; data working2 (drop=lstmag); set working; attrib start_date format=date9.; by id; retain start_date lstmag; if first.id then do; start_date=days; lstmag=mag; end; else do; if lstmag ne mag then do; start_date=days; lstmag=mag; end; end; run; proc sort data=working2 out=working3; by descending id descending days; run; data working3; set working3; attrib end_date format=date9.; retain end_date lstmag; if lstmag ne mag then do; flag="Y"; end_date=days; lstmag=mag; end; run; proc sort data=working3 out=final; by id mag; where flag="Y" and mag ne ""; run; data final (keep=id magazine start_date end_date); set final; i=1; do while (scan(mag,i,'/') ne ""); magazine=scan(mag,i,'/'); output; i=i+1; end; run;
... View more