如何将指定SAS数据步代码转换为等价的SQL查询语句
SAS前导零去除逻辑转SQL实现
原逻辑拆解
原SAS代码针对GC_OUT.TEST表做如下处理生成新表GC_OUT.ABCD_2:
- 调用
VERIFY(ASSIGNED_EMPLOYEE_CD,"0")找到字段中第一个不是'0'的字符位置,存入变量index_first_non_zero;如果字段全为'0',该函数返回0 - 调用
SUBSTR(ASSIGNED_EMPLOYEE_CD, index_first_non_zero)从定位到的位置截取到字符串末尾,得到去前导零后的字段ASSIGNED_EMPLOYEE_CD_1;如果定位位置为0,SAS默认从字符串首位开始截取,全0场景会返回原始字符串
等效SQL代码(兼容Spark SQL、Hive、Presto、MySQL 8.0+等主流引擎)
完全对齐SAS逻辑、同时保留中间计算字段的写法如下:
CREATE TABLE GC_OUT.ABCD_2 AS SELECT *, -- 计算首个非0字符位置,对齐SAS VERIFY返回规则 CASE WHEN ASSIGNED_EMPLOYEE_CD NOT REGEXP '[^0]' THEN 0 ELSE LOCATE(REGEXP_EXTRACT(ASSIGNED_EMPLOYEE_CD, '^0*([^0])', 1), ASSIGNED_EMPLOYEE_CD) END AS index_first_non_zero, -- 截取字符串得到去前导零结果,对齐SAS SUBSTR边界逻辑 CASE WHEN index_first_non_zero = 0 THEN ASSIGNED_EMPLOYEE_CD ELSE SUBSTRING(ASSIGNED_EMPLOYEE_CD, index_first_non_zero) END AS ASSIGNED_EMPLOYEE_CD_1 FROM GC_OUT.TEST;
简化写法(无需保留中间变量场景)
如果不需要保留index_first_non_zero中间字段,可以用更短的写法,注意对齐全0场景的返回逻辑:
CREATE TABLE GC_OUT.ABCD_2 AS SELECT *, CASE WHEN ASSIGNED_EMPLOYEE_CD NOT REGEXP '[^0]' THEN ASSIGNED_EMPLOYEE_CD ELSE TRIM(LEADING '0' FROM ASSIGNED_EMPLOYEE_CD) END AS ASSIGNED_EMPLOYEE_CD_1 FROM GC_OUT.TEST;
逻辑验证说明:对于输入值
000123,两种写法都会返回123,和SAS运行结果一致;对于输入值0000,会原样返回0000,和SAS边界处理逻辑完全匹配。
内容的提问来源于stack exchange,提问作者Abhinav Pandey
相关产品推荐
相关产品推荐

