SQL Server 2012按条件提取固定长度子串问题求助
解决方案:SQL Server 2012 和 Java 两种实现
针对你需要从SQL Server 2012的varchar列中提取长度为10且包含==的目标号码片段的需求,我提供两种可行方案:
一、SQL Server 2012 实现方案
方法1:使用递归CTE遍历所有可能的子串
这种方法通过递归生成所有长度为10的子串起始位置,筛选出包含==的子串后,取最右侧的结果(完全匹配你的示例预期):
WITH SplitStrings AS ( SELECT PhoneNumber, 1 AS StartPos, LEN(PhoneNumber) - 9 AS EndPos FROM YourTable -- 替换为你的实际表名 WHERE LEN(PhoneNumber) >= 10 -- 过滤长度不足10的无效记录 UNION ALL SELECT PhoneNumber, StartPos + 1, EndPos FROM SplitStrings WHERE StartPos <= EndPos ) SELECT PhoneNumber, MAX(SUBSTRING(PhoneNumber, StartPos, 10)) AS ExtractedPhone FROM SplitStrings WHERE SUBSTRING(PhoneNumber, StartPos, 10) LIKE '%==%' GROUP BY PhoneNumber OPTION (MAXRECURSION 0); -- 解除递归深度限制,适配长字符串
方法2:利用系统表生成序列,优先取右侧子串
如果你的数据量较大,递归CTE可能效率稍低,可以用系统表master..spt_values生成数字序列,直接定位最右侧符合条件的子串:
SELECT PhoneNumber, CASE -- 先检查最后10个字符是否符合条件,符合直接取 WHEN RIGHT(PhoneNumber, 10) LIKE '%==%' THEN RIGHT(PhoneNumber, 10) -- 不符合则从右往左查找第一个符合条件的10位子串 ELSE ( SELECT TOP 1 SUBSTRING(PhoneNumber, n, 10) FROM ( SELECT number AS n FROM master..spt_values WHERE type = 'P' AND number BETWEEN 1 AND LEN(PhoneNumber)-9 ) AS nums WHERE SUBSTRING(PhoneNumber, n, 10) LIKE '%==%' ORDER BY n DESC ) END AS ExtractedPhone FROM YourTable; -- 替换为你的实际表名
二、Java 实现方案
在Java中,我们可以通过正则表达式遍历所有长度为10的子串,筛选出包含==的片段并取最后一个匹配项:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class PhoneNumberExtractor { public static void main(String[] args) { // 模拟你的原始电话号码数据 String[] rawPhoneNumbers = { "23==880-3112==9435", "52==031 31466==171", "312==15850" }; // 正则表达式:通过lookahead匹配所有长度为10的子串 Pattern pattern = Pattern.compile("(?=(.{10}))"); for (String rawPhone : rawPhoneNumbers) { Matcher matcher = pattern.matcher(rawPhone); String targetPhone = null; // 遍历所有匹配的子串,记录最后一个包含==的结果 while (matcher.find()) { String candidate = matcher.group(1); if (candidate.contains("==")) { targetPhone = candidate; } } System.out.printf("原号码:%s → 提取结果:%s%n", rawPhone, targetPhone); } } }
运行这段代码后,输出结果会和你预期的完全一致:
原号码:23==880-3112==9435 → 提取结果:3112==9435 原号码:52==031 31466==171 → 提取结果:31466==171 原号码:312==15850 → 提取结果:312==15850
内容的提问来源于stack exchange,提问作者SammeAyala
相关产品推荐
相关产品推荐

