如何使用宏变量结合PROC SQL筛选两个指定日期之间的日期时间值
如何使用宏变量结合PROC SQL筛选两个指定日期之间的日期时间值
嗨,我来帮你解决这个问题!你的核心问题在于宏变量里的日期字符串和SAS的datetime数值类型不匹配,直接用BETWEEN比较肯定会出错,咱们一步步来搞定它:
首先得明确:SAS里的datetime变量(比如你的start_dtm)本质是数值型,存储的是从1960年1月1日0点到该时间的总秒数;而你定义的宏变量是字符型的日期字符串,直接比较的话SAS会按字符规则处理,结果完全不符合预期。
下面给你两种实用的解决方案:
方案一:把宏变量的日期字符串转换为SAS datetime数值
你可以用INPUT函数把宏变量里的DD-MM-YYYY格式字符串转成SAS日期值,再用DHMS函数把日期值转换成带时分秒的datetime值。因为要筛选整个日期区间的所有时间,记得把日期最大值设置为当天的23:59:59,避免漏掉当天晚些时候的数据。
完整代码示例:
PROC FORMAT; picture dmyhms . = ' ' other = '%0d-%0m-%0Y %0H:%0M:%0S' (datatype=datetime); RUN; %LET DATE_MIN = '01-09-2018'; /* DD-MM-YYYY格式的字符日期 */ %LET DATE_MAX = '30-09-2018'; PROC SQL OUTOBS=100; CREATE TABLE foo AS SELECT * FROM MY_SET WHERE start_dtm BETWEEN DHMS(INPUT(&DATE_MIN, DDMMYY10.), 0, 0, 0) /* 转成01-09-2018 00:00:00的datetime */ AND DHMS(INPUT(&DATE_MAX, DDMMYY10.), 23, 59, 59) /* 转成30-09-2018 23:59:59的datetime */ ; QUIT;
说明:DDMMYY10.是对应你宏变量DD-MM-YYYY格式的informat,确保SAS能正确解析日期;DHMS(date, hour, minute, second)函数专门用来把日期值转换成带时分秒的datetime值。
方案二:直接在宏变量中定义SAS datetime常量
这种方法更直观,直接用SAS原生的datetime常量格式('DDMONYYYY:HH:MM:SS'dt)来定义宏变量,宏变量展开后就是SAS能直接识别的datetime数值,不需要额外函数转换。
完整代码示例:
PROC FORMAT; picture dmyhms . = ' ' other = '%0d-%0m-%0Y %0H:%0M:%0S' (datatype=datetime); RUN; %LET DATE_MIN_DTM = '01SEP2018:00:00:00'dt; /* 9月1日0点的datetime常量 */ %LET DATE_MAX_DTM = '30SEP2018:23:59:59'dt; /* 9月30日23:59:59的datetime常量 */ PROC SQL OUTOBS=100; CREATE TABLE foo AS SELECT * FROM MY_SET WHERE start_dtm BETWEEN &DATE_MIN_DTM AND &DATE_MAX_DTM ; QUIT;
说明:'dt后缀是SAS的datetime常量标识,会自动把字符串转换成对应的数值,代码更简洁易懂。
关键提醒
- 你定义的
dmyhms格式只是显示用的,完全不会改变start_dtm底层的数值存储,所以筛选时一定要基于datetime数值,而不是显示出来的字符串。 - 注意日期格式的顺序:如果你的宏变量是
MM-DD-YYYY格式,要把informat改成MMDDYY10.,别搞混日和月,否则会解析出错误的日期!
两种方法都能解决问题,看你更喜欢哪种风格啦~
备注:内容来源于stack exchange,提问作者John Doe
相关产品推荐
相关产品推荐

