**************************************************************************************************** * PROGRAM OVERVIEW **************************************************************************************************** * * PROGRAM: ms_periodsoverlap.sas * * Created (mm/dd/yyyy): 12/19/2014 * Last modified: 12/19/2014 * Version: 1.0 * *-------------------------------------------------------------------------------------------------- * Used to create combinations of variables for WHERE or IF condition. * There must be at least one day of overlap between the periods. * * From Joe Celko, SQL for Smarties, 3rd Edition, Chapter 13, page 280. * Celko says that * * where arrival_date between start_date and finish_date * or depart_date between start_date and finish_date * or start_date between arrival_date and depart_date * or finish_date between arrival_date and depart_date * * is equivalent to * * where not ((depart_date < start_date) or (arrival_date > finish_date)) * * Simplifying a bit more, we get * * ( (&DEPART_DATE. >= &START_DATE.) and (&ARRIVAL_DATE. <= &FINISH_DATE.) ) * * * The DELIM= parameter is used when one of the dates is an expression containing a * space. The space character is used as a delimiter by default if an expression * needs contain a space, specify a different character in DELIM= and then use that * character to separate the start and end dates in the PERIOD parameters. Don't use * a comma as the delimiter. * * Examples: * * %put %periods_overlap(period1=rxdate, * period2=elig.DRS_Baseline_Start_Dt elig.DRS_Baseline_End_Dt); * * %put %periods_overlap(period1=rxdate @ calculated rxend, * period2=elig.DRS_Baseline_Start_Dt @ elig.DRS_Baseline_End_Dt, * delim=@); *-------------------------------------------------------------------------------------------------- * CONTACT INFO: * Mini-Sentinel Coordinating Center * info@mini-sentinel.org * *-------------------------------------------------------------------------------------------------- * CHANGE LOG: * * Version Date Initials Comment (reference external documentation when available) * ------- -------- -------- --------------------------------------------------------------- * mm/dd/yy * ***************************************************************************************************; %macro ms_periodsoverlap(period1=, period2=, delim=); %put =====> MACRO CALLED: ms_periodsoverlap v1.0; %local p1_start p1_end p2_start p2_end; %if "&DELIM." = "" %then %let delim = %bquote(%str( )); %let p1_start = %scan(&PERIOD1., 1, &DELIM.); %let p1_end = %scan(&PERIOD1., 2, &DELIM.); %let p2_start = %scan(&PERIOD2., 1, &DELIM.); %let p2_end = %scan(&PERIOD2., 2, &DELIM.); %if %quote(&P1_END.) = %quote() %then %do; %let p1_end = &P1_START.; %end; %if %quote(&P2_END.) = %quote() %then %do; %let p2_end = &P2_START.; %end; %put INFO: PERIODS_OVERLAP macro: Period 1 is &P1_START. to &P1_END. ; %put INFO: Period 2 is &P2_START. to &P2_END. ; %put INFO: Generated code is: ( (&P2_END. >= &P1_START.) and (&P2_START. <= &P1_END.) ); ( (&P2_END. >= &P1_START.) and (&P2_START. <= &P1_END.) ) %put NOTE: ******** END OF MACRO: ms_periodsoverlap v1.0 ********; %mend ms_periodsoverlap;