You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:19:28