如何用DO循环优化SAS SQL中重复的COALESCE函数代码
简化SAS重复COALESCE逻辑的两种方案
SAS PROC SQL本身不支持DO循环,要批量处理重复的COALESCE(t2.字段, t3.字段)逻辑,推荐以下两种方法:
方法一:数据步+数组+DO循环(完全实现DO循环需求)
通过数据步的数组和DO循环批量遍历字段,替代重复的COALESCE代码:
/* 数据步合并+数组循环实现批量非空取值 */ data Policy_details; merge Policy(in=t1) apr_to_dec_15a_22(in=t2 rename=(NOOF_MEMBERS_INSURED=t2_NOOF_MEMBERS_INSURED Txt_Product_Type=t2_Txt_Product_Type Txt_Type_of_Policy=t2_Txt_Type_of_Policy Boo_Type_of_Premium=t2_Boo_Type_of_Premium DATE_COMMENCEMENT=t2_DATE_COMMENCEMENT)) a15a_apr21_to_mar22(in=t3 rename=(NOOF_MEMBERS_INSURED=t3_NOOF_MEMBERS_INSURED Txt_Product_Type=t3_Txt_Product_Type Txt_Type_of_Policy=t3_Txt_Type_of_Policy Boo_Type_of_Premium=t3_Boo_Type_of_Premium DATE_COMMENCEMENT=t3_DATE_COMMENCEMENT)) ; by Txt_Policy_Number; if t1; /* 保留Policy表全部记录,等价于SQL左连接逻辑 */ /* 定义数组关联t2、t3的源字段和目标字段 */ array t2_fields[5] t2_NOOF_MEMBERS_INSURED t2_Txt_Product_Type t2_Txt_Type_of_Policy t2_Boo_Type_of_Premium t2_DATE_COMMENCEMENT; array t3_fields[5] t3_NOOF_MEMBERS_INSURED t3_Txt_Product_Type t3_Txt_Type_of_Policy t3_Boo_Type_of_Premium t3_DATE_COMMENCEMENT; array target_fields[5] NOOF_MEMBERS_INSURED Txt_Product_Type Txt_Type_of_Policy Boo_Type_of_Premium DATE_COMMENCEMENT; /* DO循环批量执行COALESCE逻辑 */ do i=1 to dim(target_fields); target_fields[i] = coalesce(t2_fields[i], t3_fields[i]); end; drop i t2_: t3_:; /* 删除临时重命名的字段 */ run;
说明:
- 先对t2、t3的字段重命名,避免合并时字段名冲突
merge+by实现按保单号匹配,in=t1确保保留原表所有记录- 数组将t2、t3的源字段和目标字段一一对应,DO循环遍历完成批量非空取值
- 新增字段时只需修改三个数组的字段列表,无需重复写COALESCE语句
方法二:宏循环生成SQL代码(保留PROC SQL风格)
如果想继续使用PROC SQL,可通过SAS宏自动生成重复的COALESCE语句:
/* 定义宏批量生成COALESCE语句 */ %macro generate_coalesce; %let fields = NOOF_MEMBERS_INSURED Txt_Product_Type Txt_Type_of_Policy Boo_Type_of_Premium DATE_COMMENCEMENT; %do i=1 %to %sysfunc(countw(&fields.)); %let field = %scan(&fields., &i.); COALESCE(t2.&field., t3.&field.) as &field. %if &i. < %sysfunc(countw(&fields.)) %then ,; /* 最后一个字段后不加逗号 */ %end; %mend; proc sql; create table Policy_details as select t1.* , %generate_coalesce /* 调用宏生成COALESCE语句 */ from Policy as t1 left join apr_to_dec_15a_22 as t2 on t1.Txt_Policy_Number = t2.Txt_Policy_Number left join a15a_apr21_to_mar22 as t3 on t1.Txt_Policy_Number = t3.Txt_Policy_Number ; quit;
说明:
- 宏内定义需要处理的字段列表,通过
%do循环遍历每个字段,自动生成对应的COALESCE代码 - 维护时只需修改
%let fields中的字段名,无需手动重复编写COALESCE语句
内容的提问来源于stack exchange,提问作者Lokesh
相关产品推荐
相关产品推荐

