2016-10-31 6 views
0

Это, скорее всего, простой вопрос, но я еще не смог его понять.SAS Where Clause with Macro Variables

Мне нужно получить некоторые данные из набора данных SAS, где DATE находится в пределах диапазона 6 месяцев (например, от 01JAN2017 до 30JUN2017). Я попытался выполнить следующий код, но это приводит к ошибке. Есть предположения? Я уверен, что это что-то просто ...

%let start1 = %Sysfunc(InputN(01JAN2017 , Date9.)) ; 
%let start2 = %sysfunc(putN(&start1, date9)); 
%put start1 &start1 start2 &start2; 

%let end1 = %sysfunc(inputn(30JUN2017,Date9.)); 
%let end2 = %sysfunc(putN(&end1, date9)); 
%put end1 &end1 end2 &end2; 

proc print data=ext.account_detail (obs = 10); 
    where manufacturer = 'FORD' or product_segment = 'CHRYSLER' 
     and manufacturer_date between &start2 and &end2; 
run; 

В результате получается следующее сообщение об ошибке: Примечание: Линия генерируется макропеременной «START2».

26   01JAN2017 
       _______ 
       22 
       76 
ERROR: Syntax error while parsing WHERE clause. 
ERROR 22-322: Syntax error, expecting one of the following: !!, *, **, +, -, /, AND, ||. 
ERROR 76-322: Syntax error, statement will be ignored. 

ответ

1

Вы поместили строку 01JAN2017 в переменную макроса START2, а затем попробовали нас в инструкции WHERE без предварительного преобразования ее в фактическое значение даты.

Если вы хотите, чтобы ваши макропеременные были отформатированы таким образом, используйте синтаксис date literal в инструкции WHERE.

where manufacturer = 'FORD' or product_segment = 'CHRYSLER' 
    and manufacturer_date between "&start2"D and "&end2"D 
; 
0

Это идет в другом направлении полностью, но функция intnx хорошо подходит для выполнения этой задачи. Это позволяет вам увеличивать время с интервалом по вашему выбору. Синтаксис: intnx('interval', fromdate, num_periods, 'alignment').

Несколько примеров:

intnx('month', '20FEB17'd, 0, 'beg') will return 01FEB2017

intnx('month', '20FEB17'd, 2, 'end') will return 30APR2017

intnx('month', '20FEB17'd, -1, 'beg') will return 01JAN2017

В первом случае SAS чтения 20FEB17 в качестве входных данных, сдвинула ноль месяцев, и возвращает начало этого периода , Во втором примере он переносит дату ввода на два месяца и возвращает конец этого периода. В последнем примере мы видим, что мы можем сдвинуться назад во времени, и за месяц до нашей даты ввода.

В вашем конкретном случае вы должны написать что-то вроде ... manufacturer_date between '01JAN17'd and intnx('month', '01JAN17'd, 5, 'end').

Обратите внимание, что несколько контр-интуитивно, нам нужно только сдвинуть вперед пять месяцев, чтобы захватить шестимесячное окно. Это потому, что выравнивание «конец» дает нам последний месяц. Иными словами, JAN -> FEB -> MAR -> APR -> MAY -> JUN требует 5 шагов. Также обратите внимание, что я приводил только примеры с ежемесячными сменами. SAS также допускает ежегодные смены, полугодичные сдвиги, и вы можете даже запрограммировать собственный интервал, если это необходимо.