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

SQL实现按最大长度30拆分字符串且不截断完整单词的解决方案问询

解决方案:按单词拆分字符串为指定长度的多行

我完全懂你的困扰——直接用SUBSTRING按固定长度硬切,很容易把好好的单词劈成两半,完全不符合需求。下面给你一个基于递归CTE的方案,它会自动找到每行的最后一个空格来拆分,既保证每行长度不超30字符,又不会截断完整单词。

完整实现代码

DECLARE @FullAddress VARCHAR(MAX)= '216 Apartment123 AreaArea SampleWord1 Word2 MiddleTown Upper1Location Another5 NewYork';
DECLARE @MaxLength INT = 30;

WITH SplitAddress AS (
    -- 初始化:处理第一个文本片段
    SELECT
        1 AS RowNum,
        -- 取前30字符内的最后一个空格位置,确保不截断单词
        CASE 
            WHEN LEN(@FullAddress) <= @MaxLength THEN @FullAddress
            ELSE LEFT(@FullAddress, @MaxLength - CHARINDEX(' ', REVERSE(LEFT(@FullAddress, @MaxLength))))
        END AS Result,
        -- 计算剩余未处理的文本
        CASE 
            WHEN LEN(@FullAddress) <= @MaxLength THEN ''
            ELSE LTRIM(SUBSTRING(@FullAddress, @MaxLength - CHARINDEX(' ', REVERSE(LEFT(@FullAddress, @MaxLength))) + 1, LEN(@FullAddress)))
        END AS RemainingText
    UNION ALL
    -- 递归处理剩余文本,直到所有内容拆分完成
    SELECT
        RowNum + 1,
        CASE 
            WHEN LEN(RemainingText) <= @MaxLength THEN RemainingText
            ELSE LEFT(RemainingText, @MaxLength - CHARINDEX(' ', REVERSE(LEFT(RemainingText, @MaxLength))))
        END,
        CASE 
            WHEN LEN(RemainingText) <= @MaxLength THEN ''
            ELSE LTRIM(SUBSTRING(RemainingText, @MaxLength - CHARINDEX(' ', REVERSE(LEFT(RemainingText, @MaxLength))) + 1, LEN(RemainingText)))
        END
    FROM SplitAddress
    WHERE RemainingText <> ''
)
SELECT RowNum AS [Row], Result
FROM SplitAddress;

代码逻辑说明

  • 递归CTE核心:通过SplitAddress这个公用表表达式,先处理第一行,再递归处理剩下的文本,直到没有剩余内容。
  • 避免单词截断的关键:用REVERSE(LEFT(文本, 30))反转前30个字符,再用CHARINDEX找到第一个空格(也就是原文本前30字符里的最后一个空格),这样就能保证当前行只包含完整的单词。
  • 清理空格:用LTRIM去掉剩余文本开头的空格,避免拆分后的行出现前置空格。

运行结果

执行这段代码后,会完全符合你的期望输出:

+-----+------------------------------+
| Row | Result                       |
+-----+------------------------------+
| 1   | 216 Apartment123 AreaArea    |
| 2   | SampleWord1 Word2 MiddleTown |
| 3   | Upper1Location Another5      |
| 4   | NewYork                      |
+-----+------------------------------+

极端情况处理(可选)

如果你的字符串里存在单个单词长度超过30字符的情况(比如一个35字符的长单词),上面的代码会因为找不到空格而报错。你可以修改CASE判断,加入无空格时的处理逻辑,直接截取前30字符:

CASE 
    WHEN LEN(RemainingText) <= @MaxLength THEN RemainingText
    ELSE 
        -- 如果前30字符里没有空格,直接截取30位(避免无限递归)
        CASE WHEN CHARINDEX(' ', LEFT(RemainingText, @MaxLength)) = 0 THEN LEFT(RemainingText, @MaxLength)
             ELSE LEFT(RemainingText, @MaxLength - CHARINDEX(' ', REVERSE(LEFT(RemainingText, @MaxLength))))
        END
END

内容的提问来源于stack exchange,提问作者Teknas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 08:23:00