带有宏变量的 SAS Where 子句

SAS Where Clause with Macro Variables

这很可能是一个简单的问题,但我还没有弄明白。

我需要从日期在 6 个月范围内(例如 2017 年 1 月 1 日至 2017 年 6 月 30 日)的 SAS 数据集中检索一些数据 我尝试了 运行 以下代码,但它导致了错误。有什么想法吗?我确定这很简单...

%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.

这完全是另一个方向,但是 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 读取为输入,将其移动零个月,并且 returns 该期间的开始。在第二个示例中,它将我们的输入日期向前移动两个月,并且 returns 该期间的结束。在最后一个示例中,我们看到我们能够及时向后移动,比输入日期早一个月。

在您的特定情况下,您会写类似... manufacturer_date between '01JAN17'd and intnx('month', '01JAN17'd, 5, 'end').

请注意,有些违反直觉,我们只需要向前移动五个月即可捕获六个月 window。这是因为 'end' 对齐给了我们最后一个月。换句话说,JAN -> FEB -> MAR -> APR -> MAY -> JUN 需要 5 个步骤。另请注意,我仅给出了每月轮班的示例。 SAS 还允许每年轮班、半年轮班,如果需要,您甚至可以编写自定义间隔。

您将字符串 01JAN2017 放入宏变量 START2 中,然后尝试在 WHERE 语句中使用它,而没有先将其转换为实际日期值。

如果您希望以这种方式格式化您的宏变量,请在您的 WHERE 语句中使用日期文字语法。

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