Teradata中不同长度账户号字段统一截取后四位的实现方法
账户号统一提取后四位的实现方案
针对不同长度的账户号提取末尾4位的需求,不需要针对每个长度硬编码固定截取位置,通过反向定位的逻辑可以兼容所有长度场景,覆盖全部已知的11位、9位、8位、7位账户号场景,同时适配后续可能出现的其他长度规则。
推荐方案:无硬编码反向截取
这类方案不需要预先统计所有可能的账户长度,只要账户总长度≥4位,即可准确提取最末尾4位字符,完全匹配预期输出效果:
- 支持
RIGHT函数的数据库(MySQL、PostgreSQL、SQL Server、Oracle 11g及以上等),直接调用内置右截取函数实现:
实际匹配校验:SELECT RIGHT(ACCT_NBR, 4) AS BNK_ACCT_NBR FROM NAMEOFTABLE;- 11位账户号
76587990891→ 输出0891 - 9位账户号
654378908→ 输出8908 - 8位账户号
45643456→ 输出3456
完全符合预期结果。
- 11位账户号
- 不支持
RIGHT函数的老旧数据库,通过动态计算截取起始位置实现同等效果:
由于需要取最后4位,截取起始位置 = 账户号总长度 - 3,从该位置向后连续截取4个字符即可覆盖字符串末尾,写法为:SELECT SUBSTRING(ACCT_NBR, LEN(ACCT_NBR) - 3, 4) AS BNK_ACCT_NBR FROM NAMEOFTABLE;
备选方案:固定长度分支适配
如果坚持按照原思路,针对每一类已知长度单独匹配截取规则,可通过CASE语句做分支判断,示例代码:
SELECT CASE WHEN LEN(ACCT_NBR) = 11 THEN SUBSTRING(ACCT_NBR, 7, 4) WHEN LEN(ACCT_NBR) = 9 THEN SUBSTRING(ACCT_NBR, 5, 4) WHEN LEN(ACCT_NBR) = 8 THEN SUBSTRING(ACCT_NBR, 5, 4) WHEN LEN(ACCT_NBR) = 7 THEN SUBSTRING(ACCT_NBR, 4, 4) ELSE NULL END AS BNK_ACCT_NBR FROM NAMEOFTABLE;
这类方案的局限性较强:所有长度规则为硬编码形式,后续如果业务侧新增其他长度的账户号,必须同步修改SQL逻辑,维护成本较高。
落地注意事项
- 提前校验
ACCT_NBR字段的存储类型,如果是数字类型存储的账户号,需要先转换为字符串格式再截取,避免账户号开头的前导0被数据库自动截断丢失。 - 增加异常值判断:如果存在账户号长度不足4位的记录,需要单独做逻辑适配,避免动态计算的截取起始位置小于1,引发数据库语法报错。
内容的提问来源于stack exchange,提问作者Bilsed421
相关产品推荐
相关产品推荐

