SQL Server:仅提取文本中括号内的数字
提取SQL Server文本列中括号间的数字
嘿,我来帮你搞定这个需求!针对你存储在VARCHAR列里的文本,要提取所有位于括号()之间的数字,这里有两种实用方案,根据你的SQL Server版本选就行:
方案一:通用版(适配所有SQL Server版本)
如果你的SQL Server版本比较旧(比如2016及以前),可以用递归CTE来逐个提取每个括号里的数字,轻松处理单条文本里多个括号的情况:
WITH RecursiveCTE AS ( -- 初始行:获取每条记录的ID、原始文本,以及第一个括号的位置 SELECT YourIDColumn, YourTextColumn AS OriginalText, -- 定位第一个左括号 PATINDEX('%(%', YourTextColumn) AS OpenParenPos, -- 定位对应右括号(从左括号后开始查找) PATINDEX('%)%', YourTextColumn) AS CloseParenPos, -- 提取第一个括号内的内容(如果存在有效括号对) CASE WHEN PATINDEX('%(%', YourTextColumn) > 0 AND PATINDEX('%)%', YourTextColumn) > PATINDEX('%(%', YourTextColumn) THEN SUBSTRING(YourTextColumn, PATINDEX('%(%', YourTextColumn) + 1, PATINDEX('%)%', YourTextColumn) - PATINDEX('%(%', YourTextColumn) - 1) ELSE NULL END AS ExtractedNumber, -- 生成剩余文本:去掉已经处理过的第一个括号部分 CASE WHEN PATINDEX('%)%', YourTextColumn) > 0 THEN SUBSTRING(YourTextColumn, PATINDEX('%)%', YourTextColumn) + 1, LEN(YourTextColumn)) ELSE '' END AS RemainingText FROM YourTableName UNION ALL -- 递归部分:循环处理剩余文本里的下一个括号 SELECT YourIDColumn, OriginalText, PATINDEX('%(%', RemainingText) AS OpenParenPos, PATINDEX('%)%', RemainingText) AS CloseParenPos, CASE WHEN PATINDEX('%(%', RemainingText) > 0 AND PATINDEX('%)%', RemainingText) > PATINDEX('%(%', RemainingText) THEN SUBSTRING(RemainingText, PATINDEX('%(%', RemainingText) + 1, PATINDEX('%)%', RemainingText) - PATINDEX('%(%', RemainingText) - 1) ELSE NULL END AS ExtractedNumber, CASE WHEN PATINDEX('%)%', RemainingText) > 0 THEN SUBSTRING(RemainingText, PATINDEX('%)%', RemainingText) + 1, LEN(RemainingText)) ELSE '' END AS RemainingText FROM RecursiveCTE WHERE RemainingText <> '' ) -- 最终结果:过滤空值,按原始记录分组聚合数字 SELECT YourIDColumn, OriginalText, -- 旧版本用FOR XML PATH拼接,2017+可替换为STRING_AGG(ExtractedNumber, ', ') STUFF((SELECT ', ' + ExtractedNumber FROM RecursiveCTE r2 WHERE r2.YourIDColumn = r1.YourIDColumn AND ExtractedNumber IS NOT NULL FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, '') AS AllExtractedNumbers FROM RecursiveCTE r1 GROUP BY YourIDColumn, OriginalText;
代码说明:
- 递归CTE会逐次扫描文本,定位每一对括号的位置,提取中间内容
- 最后通过
FOR XML PATH把同一行的多个数字拼接成逗号分隔的字符串(2017+版本用STRING_AGG会更简洁)
方案二:简化版(SQL Server 2017+)
如果你用的是SQL Server 2017或更新版本,支持正则表达式函数,那可以用REGEXP_REPLACE一步到位提取所有括号内的数字,再用STRING_AGG聚合:
SELECT YourIDColumn, YourTextColumn, STRING_AGG(value, ', ') AS AllExtractedNumbers FROM YourTableName CROSS APPLY STRING_SPLIT( REGEXP_REPLACE(YourTextColumn, '.*?\((\d+)\)|.', '$1'), ',' ) WHERE value <> '' GROUP BY YourIDColumn, YourTextColumn;
代码说明:
REGEXP_REPLACE(YourTextColumn, '.*?\((\d+)\)|.', '$1'):用正则精准匹配括号里的数字,把其他无关内容替换为空,得到初步的数字串STRING_SPLIT拆分后过滤空值,再用STRING_AGG拼接成干净的逗号分隔数字列表
额外提示:
如果你的文本里只有单个括号对,那可以直接用简化写法,不用递归或正则:
SELECT YourTextColumn, SUBSTRING(YourTextColumn, PATINDEX('%(%', YourTextColumn) + 1, PATINDEX('%)%', YourTextColumn) - PATINDEX('%(%', YourTextColumn) - 1) AS ExtractedNumber FROM YourTableName WHERE PATINDEX('%(%', YourTextColumn) > 0 AND PATINDEX('%)%', YourTextColumn) > PATINDEX('%(%', YourTextColumn);
内容的提问来源于stack exchange,提问作者Arslan Ahmed
相关产品推荐
相关产品推荐

