SQL如何提取字段内第4个与第5个冒号之间的指定内容?
SQL提取指定序号冒号间内容的实现方案
你之前用的固定偏移截取SUBSTRING(var_value,15,4)稳定性很差,只要字段前置内容长度发生变化,截取结果就会出错,建议用动态定位分隔符的写法实现需求。
方案1:适用于MySQL、Hive、SparkSQL等支持SUBSTRING_INDEX的引擎
这是最简洁的写法,不需要逐层嵌套定位位置,直接通过分段截取拿到目标内容:
SUBSTRING_INDEX( SUBSTRING_INDEX(var_value, ':', 5), ':', -1 ) AS TargetOutput
逻辑说明:
- 内层
SUBSTRING_INDEX(var_value, ':', 5)会先截取到第5个冒号之前的全部内容,对你的示例字符串来说,返回结果是do::this from the info::thisisatest - 外层函数再从上述结果中,取最后一个冒号之后的片段,刚好就是第4个和第5个冒号之间的
thisisatest,完全匹配你的需求 - 即使字段里存在连续冒号(比如你示例中的
::),这个写法也能正常识别,不会跳过连续分隔符。
方案2:适用于SQL Server、PostgreSQL等不支持SUBSTRING_INDEX的引擎
通过逐层定位每个冒号的位置,再按位置截取目标片段,以SQL Server语法为例:
SELECT SUBSTRING(var_value, pos4 + 1, pos5 - pos4 - 1) AS TargetOutput FROM ( SELECT var_value, CHARINDEX(':', var_value, pos3 + 1) AS pos4, CHARINDEX(':', var_value, CHARINDEX(':', var_value, pos3 + 1) + 1) AS pos5 FROM ( SELECT var_value, CHARINDEX(':', var_value, pos2 + 1) AS pos3 FROM ( SELECT var_value, CHARINDEX(':', var_value, CHARINDEX(':', var_value, 1) + 1) AS pos2 FROM ( SELECT var_value, CHARINDEX(':', var_value, 1) AS pos1 ) t1 ) t2 ) t3 ) t4
如果是PostgreSQL,把代码里的CHARINDEX替换成对应位置查找函数即可,核心逻辑一致:从前往后逐个找到第4、第5个冒号的下标,截取两个下标中间的字符串。
注意事项
- 不要依赖固定字符偏移做截取,只要业务字段内容长度有调整,固定偏移的写法就会返回错误结果
- 上线前可以先用你提供的测试字符串
do::this from the info::thisisatest::K::99做验证,两种写法返回结果均为目标值thisisatest
内容的提问来源于stack exchange,提问作者Gavin Mazza
相关产品推荐
相关产品推荐

