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

如何在SAS自定义函数中访问表值并获取SQL查询返回值?

在SAS EG中实现带银行假日的月度工作日函数

核心思路

在SAS的FCMP自定义函数中直接嵌入PROC SQL,通过SELECT INTO语句将查询结果赋值给函数的局部变量,再用这些变量完成最终的工作日计算;如果需要返回多个值,可通过输出参数实现。

代码实现示例

假设你的银行假日表名为bank_holidays,包含日期列holiday_date,以下是完整的函数定义:

1. 单返回值函数(返回工作日天数)

/* 创建函数并存储到work.funcs库 */
PROC FCMP OUTLIB=work.funcs.day_calc;
    /* 输入参数:指定日期(用来确定统计的月份),返回值为数值型 */
    FUNCTION calc_month_workdays(input_date DATE) RETURNS NUMERIC;
        /* 声明存储SQL结果的局部变量 */
        DECLARE num holiday_count;
        DECLARE num month_start;
        
        /* 用SQL获取当月已过的银行假日数量,以及当月起始日期 */
        PROC SQL NOPRINT;
            SELECT 
                COUNT(holiday_date),
                INTNX('MONTH', input_date, 0, 'BEGINNING')
                INTO :holiday_count, :month_start
            FROM bank_holidays
            WHERE holiday_date BETWEEN :month_start AND input_date;
        QUIT;
        
        /* 计算当月已过的总天数 */
        DECLARE num passed_days;
        passed_days = input_date - month_start + 1;
        
        /* 计算当月已过的周末天数 */
        DECLARE num weekend_days;
        weekend_days = 0;
        DO i = month_start TO input_date;
            IF WEEKDAY(i) IN (1,7) THEN weekend_days = weekend_days + 1;
        END;
        
        /* 计算最终工作日天数 */
        DECLARE num work_days;
        work_days = passed_days - weekend_days - holiday_count;
        
        RETURN work_days;
    ENDSUB;
RUN;

/* 注册函数库,让SAS能识别自定义函数 */
OPTIONS CMPLIB=work.funcs;

2. 带输出参数的函数(返回工作日天数+银行假日数)

如果需要同时返回银行假日数量等额外值,可通过OUTARGS定义输出参数:

PROC FCMP OUTLIB=work.funcs.day_calc;
    /* OUTARGS后声明输出参数,函数仍返回工作日天数 */
    FUNCTION calc_month_workdays(input_date DATE, OUTARGS holiday_count NUMERIC) RETURNS NUMERIC;
        DECLARE num month_start;
        
        PROC SQL NOPRINT;
            SELECT 
                COUNT(holiday_date),
                INTNX('MONTH', input_date, 0, 'BEGINNING')
                INTO :holiday_count, :month_start
            FROM bank_holidays
            WHERE holiday_date BETWEEN :month_start AND input_date;
        QUIT;
        
        /* 计算周末天数与工作日天数 */
        DECLARE num passed_days weekend_days work_days;
        passed_days = input_date - month_start + 1;
        weekend_days = 0;
        DO i = month_start TO input_date;
            IF WEEKDAY(i) IN (1,7) THEN weekend_days = weekend_days + 1;
        END;
        work_days = passed_days - weekend_days - holiday_count;
        
        RETURN work_days;
    ENDSUB;
RUN;

OPTIONS CMPLIB=work.funcs;

/* 使用示例 */
DATA test;
    target_date = TODAY();
    /* 调用函数,同时获取工作日天数和银行假日数 */
    work_days = calc_month_workdays(target_date, holiday_count);
    PUT "截至" target_date DATE9. ",当月工作日:" work_days "天,银行假日:" holiday_count "天";
RUN;

关键注意事项

  • 确保银行假日表的库路径正确,若表不在work库,需在SQL中指定完整库名(如lib.bank_holidays)。
  • PROC SQL需加NOPRINT参数,避免查询结果输出到日志。
  • 局部变量必须先用DECLARE声明,否则无法被SQL赋值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 02:34:53