You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PROC SQL中生成最近五个4月1日的日期列表?

问题解决:生成包含最近五个4月1日的SAS表

问题描述

我想要创建一个包含最近五个4月1日的表,例如当前运行时,表中数据应为:

Snapshot
1APR2023
1APR2022
1APR2021
1APR2020
1APR2019

尝试了以下代码,但运行出现语法错误:

/* Create an empty table */ 
proc sql;
   create table FinancialYearStarts (
      StartDate date
   );
quit;

/* Define the start date of the financial year */
%let FinancialYearStartDate = '01APR';

/* Use a DO loop to insert the last five starts of the financial year */
%macro PopulateFinancialYearStarts;
   %do i = 0 %to 4;
      proc sql;
         insert into FinancialYearStarts (StartDate)
         values (intnx('year', today(), -&i, 'sameday') + input(&FinancialYearStartDate., date9.));
      quit;
   %end;
%mend;

/* Execute the macro to populate the table */
%PopulateFinancialYearStarts;

错误原因

  1. 语法错误:宏变量FinancialYearStartDate定义时带单引号,代入input函数后会变成input(''01APR'', date9.),嵌套的单引号直接引发语法报错。
  2. 逻辑错误:intnx('year', today(), -&i, 'sameday')返回的是当前日期往前推i年的同一天,加上input('01APR',date9.)得到的是1960年4月1日的日期数值,最终结果完全偏离目标的每年4月1日。

解决方案

方案1:修正原有宏逻辑

调整宏变量定义和日期构造方式,确保生成正确的每年4月1日:

/* 创建空表 */
proc sql;
   create table FinancialYearStarts (
      StartDate date format=date9.
   );
quit;

/* 定义财年起始的月日(不带引号) */
%let FinancialYearStartMD = 01APR;

/* 批量插入最近5个4月1日的宏 */
%macro PopulateFinancialYearStarts;
   %do i = 0 %to 4;
      /* 获取目标年份 */
      %let target_year = %eval(%sysfunc(year(%sysfunc(today()))) - &i);
      proc sql;
         insert into FinancialYearStarts (StartDate)
         values (input("&FinancialYearStartMD.&target_year", date9.));
      quit;
   %end;
%mend;

/* 执行宏 */
%PopulateFinancialYearStarts;

方案2:高效非宏实现(推荐)

无需宏循环,用data步一次性生成所有数据,代码更简洁高效:

/* 直接生成包含最近5个4月1日的表 */
data FinancialYearStarts;
   format StartDate date9.;
   current_year = year(today());
   do i = 0 to 4;
      /* 用mdy函数构造4月1日:mdy(月份, 日期, 年份) */
      StartDate = mdy(4, 1, current_year - i);
      output;
   end;
   drop current_year i;
run;

方案3:Proc SQL 批量生成

如果偏好Proc SQL,可通过生成序列的方式批量构造日期:

proc sql;
   create table FinancialYearStarts as
   select mdy(4, 1, year(today()) - i) as StartDate format=date9.
   from (select 0 as i from dual union all
         select 1 as i from dual union all
         select 2 as i from dual union all
         select 3 as i from dual union all
         select 4 as i from dual);
quit;

内容的提问来源于stack exchange,提问作者supercoolphysicist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 09:15:31