为何SAS Enterprise Guide中Compress函数在PROC SQL左连接中失效?
解决SAS EG中PROC SQL左连接使用COMPRESS函数的问题
我之前在迁移SAS Base程序到EG时也碰到过类似的字符变量匹配问题,尤其是像债券参考利率这类带多余空格的字符字段,直接在ON条件里用COMPRESS确实会出现兼容性问题。给你几个经过验证的可行方案:
方案一:提前预处理压缩字段(最稳妥)
先在Data步里为两个表生成压缩后的新字段,再用这个新字段做连接条件。这样避开了PROC SQL对ON条件中函数调用的解析限制,同时也方便后续重复使用这个清洗后的字段:
/* 预处理主表,生成压缩后的参考利率字段 */ data have_clean; set have; RefRate_CMP = compress(RefRate); /* 去掉所有空格及其他默认可压缩字符 */ run; /* 预处理关联表 */ data have1_clean; set have1; RefRate_CMP = compress(RefRate); run; /* 使用清洗后的字段做左连接 */ proc sql; create table Want as select a.*, b.Var1, b.Var2, b.Var3, b.Var4, b.Var5, b.Var6, b.Var7, b.Var8, b.Var9 from have_clean as a left join have1_clean as b on a.RefRate_CMP = b.RefRate_CMP; quit;
方案二:在PROC SQL中用子查询预处理字段
如果不想额外生成中间表,可以直接在PROC SQL里用子查询完成字段压缩,再进行连接,逻辑和方案一一致,但更紧凑:
proc sql; create table Want as select a.*, b.Var1, b.Var2, b.Var3, b.Var4, b.Var5, b.Var6, b.Var7, b.Var8, b.Var9 from ( select *, compress(RefRate) as RefRate_CMP from Have ) as a left join ( select *, compress(RefRate) as RefRate_CMP from Have1 ) as b on a.RefRate_CMP = b.RefRate_CMP; quit;
方案三:强制指定压缩后字段的长度(针对特殊字符场景)
如果遇到的是特殊空格(比如非ASCII空格)或者压缩后字段长度不一致导致的匹配失败,可以在压缩时用PUT函数指定统一的字符长度,确保两边的匹配字段完全一致:
proc sql; create table Want as select a.*, b.Var1, b.Var2, b.Var3, b.Var4, b.Var5, b.Var6, b.Var7, b.Var8, b.Var9 from Have as a left join Have1 as b on put(compress(a.RefRate), $20.) = put(compress(b.RefRate), $20.); quit;
这里的$20.可以根据你实际的债券参考利率字段长度调整,确保能容纳所有清洗后的字符内容。
补充说明
之所以直接在ON条件里用compress(a.ID)=compress(b.ID)会失效,大概率是SAS EG的PROC SQL优化器对连接条件中的函数调用处理逻辑和Base SAS略有差异,提前预处理字段可以彻底避开这个兼容性问题,同时也让代码的可读性和维护性更好。
内容的提问来源于stack exchange,提问作者78282219
相关产品推荐
相关产品推荐

