SQL Server查询如何提取@与后续空格间的所有匹配子串
SQL Server 提取@标记后用户名实现方法
实现逻辑
利用规则特性:所有待提取内容都位于@和其后第一个空格之间,且每个@后必然存在对应空格,因此可以通过拆分字符串逐段提取,不需要依赖未内置的正则函数:
- 将原字符串按
@字符拆分 - 跳过拆分结果中第一个分段(该段是第一个
@之前的内容,无匹配值) - 对剩余每个分段,截取第一个空格之前的子串,即为单个匹配结果
- 把所有匹配结果用逗号拼接为最终输出
版本适配代码
SQL Server 2022 及以上版本(含Azure SQL)
该版本支持带序数参数的STRING_SPLIT,可以保证拆分顺序不混乱,写法最简洁:
-- 定义待处理字符串,实际业务使用时替换为表字段即可 DECLARE @input_str NVARCHAR(MAX) = 'Hello @user1 and @user2 how are you?'; SELECT STRING_AGG(SUBSTRING(split_val, 1, CHARINDEX(' ', split_val) - 1), ', ') AS extract_result FROM STRING_SPLIT(@input_str, '@', 1) WHERE ordinal > 1;
执行结果完全匹配给出的样例:
- 输入
hello @user1, how are you?,输出user1 - 输入
Hello @user1 and @user2 how are you?,输出user1, user2 - 输入
@user1 and @user2 replied,输出user1, user2
SQL Server 2008 - 2019 兼容版本
低版本没有带序数的拆分函数,可以用递归CTE逐次定位@和空格的位置提取,兼容性更强:
DECLARE @input_str NVARCHAR(MAX) = 'hello @user1 ,@user2 ,@... , how are you?'; WITH match_records AS ( -- 定位第一个@的位置,提取第一个匹配值 SELECT STUFF(@input_str, 1, CHARINDEX('@', @input_str), '') AS rest_content, SUBSTRING( @input_str, CHARINDEX('@', @input_str) + 1, CHARINDEX(' ', @input_str, CHARINDEX('@', @input_str)) - CHARINDEX('@', @input_str) - 1 ) AS single_match WHERE CHARINDEX('@', @input_str) > 0 UNION ALL -- 递归定位剩余内容里的@,循环提取 SELECT STUFF(rest_content, 1, CHARINDEX('@', rest_content), '') AS rest_content, SUBSTRING( rest_content, CHARINDEX('@', rest_content) + 1, CHARINDEX(' ', rest_content, CHARINDEX('@', rest_content)) - CHARINDEX('@', rest_content) - 1 ) AS single_match FROM match_records WHERE CHARINDEX('@', rest_content) > 0 ) -- 2017及以上版本可以直接用STRING_AGG拼接 -- SELECT STRING_AGG(single_match, ', ') AS extract_result FROM match_records; -- 2016及以下版本用FOR XML PATH拼接,兼容所有低版本 SELECT STUFF( (SELECT ', ' + single_match FROM match_records FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '' ) AS extract_result;
说明:当前写法基于「每个@后必然存在空格」的规则实现,不需要额外处理边界异常。如果后续存在@位于字符串末尾、@后无有效内容的场景,在提取前加
CHARINDEX(' ', 待截取分段) > 0的判断即可避免报错。
内容的提问来源于stack exchange,提问作者AIDEN IV
相关产品推荐
相关产品推荐

