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

如何从字符串中提取仅字母?含SQL Server 2012查询方案

在SQL Server 2012中提取字符串里的仅字母内容

嘿,我来帮你搞定这个问题!看了你的测试数据和需求,就是要把字符串里所有数字、符号、标点这些非字母内容全去掉,只留下A-Za-z的字母对吧?你之前尝试的代码只能处理开头的部分,中间夹杂的非字母搞不定,我给你两个实用的方法:

方法一:用递归CTE直接处理

这个方法不用额外创建函数,直接写查询就能搞定,适合一次性的需求:

WITH TestData AS (
    SELECT ',1,,3,,Mango,.,.,Apple,Orange' AS InputString, 'MangoAppleOrange' AS ExpectedString
    UNION ALL
    SELECT ',,,99,,,Apple,.,.,,Mango,,,Grape,,', 'AppleMangoGrape'
    UNION ALL
    SELECT ',,,99,,-,Banana,/....*,.,,Mango,,,Grape,,', 'BananaMangoGrape'
),
RecursiveExtract AS (
    SELECT 
        InputString,
        ExpectedString,
        CAST('' AS VARCHAR(MAX)) AS ExtractedString,
        1 AS Position
    FROM TestData
    UNION ALL
    SELECT 
        InputString,
        ExpectedString,
        ExtractedString + CASE WHEN SUBSTRING(InputString, Position, 1) LIKE '[A-Za-z]' THEN SUBSTRING(InputString, Position, 1) ELSE '' END,
        Position + 1
    FROM RecursiveExtract
    WHERE Position <= LEN(InputString)
)
SELECT 
    InputString,
    ExpectedString,
    ExtractedString AS ActualString
FROM RecursiveExtract
WHERE Position = LEN(InputString) + 1
ORDER BY InputString;

方法二:自定义标量函数,方便重复调用

如果你以后经常要用到这个提取逻辑,创建一个函数会更省心:

CREATE FUNCTION dbo.ExtractOnlyLetters(@InputString VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
    DECLARE @Result VARCHAR(MAX) = '';
    DECLARE @Position INT = 1;
    
    WHILE @Position <= LEN(@InputString)
    BEGIN
        IF SUBSTRING(@InputString, @Position, 1) LIKE '[A-Za-z]'
        BEGIN
            SET @Result = @Result + SUBSTRING(@InputString, @Position, 1);
        END
        SET @Position = @Position + 1;
    END
    
    RETURN @Result;
END;

用的时候直接调用这个函数就行,比如:

SELECT 
    InputString,
    ExpectedString,
    dbo.ExtractOnlyLetters(InputString) AS ActualString
FROM (
    SELECT ',1,,3,,Mango,.,.,Apple,Orange' AS InputString, 'MangoAppleOrange' AS ExpectedString
    UNION ALL
    SELECT ',,,99,,,Apple,.,.,,Mango,,,Grape,,', 'AppleMangoGrape'
    UNION ALL
    SELECT ',,,99,,-,Banana,/....*,.,,Mango,,,Grape,,', 'BananaMangoGrape'
) AS TestData;

简单说下这两种方法的逻辑:

  • 递归CTE是一层一层遍历字符串的每个字符位置,判断当前字符是不是字母,是的话就加到结果里,直到把整个字符串遍历完。
  • 自定义函数用的是WHILE循环,逻辑和CTE差不多,但封装成函数后,每次用的时候直接调用就行,不用重复写递归的代码。

你之前用PATINDEX的思路只能找到第一个不符合要求的字符位置,只能提取开头的有效部分,没法处理中间夹杂的非字母内容,所以上面这两种方法就能完美解决你的需求啦~

内容的提问来源于stack exchange,提问作者Prasanna Kumar J

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:00:32