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

如何在SQL Server中合并不同长度的重复值?

SQL查询中合并看似相同但含不可见字符的重复值

原始查询语句

SELECT 
    *, 
    LEN(Test) LENofTEST, 
    DATALENGTH(Test) DataLENofTEST, 
    CAST(Test AS VARBINARY(30)) ExtraColumn
FROM
    (SELECT 
         TRIM(SOS1 + ',' + REPLACE(PANO20, ' ', '')) AS 'Test', 
         COUNT(SOS1 + ',' + REPLACE(PANO20, ' ', '')) AS 'COUNTR'
     FROM 
         MyServerName.dbo.MyTableName
     WHERE 
         PANO20 LIKE '%701001207%'
     GROUP BY 
         TRIM(SOS1 + ',' + REPLACE(PANO20, ' ', ''))) A

查询结果

Test            COUNTR   LENofTEST   DataLENofTEST   ExtraColumn
-----------------------------------------------------------------
100,701001207   1        13             13   0x3130302C373031303031323037
100,701001207   1        14             14   0x3130302C373031303031323037A0
123,701001207   1        13             13   0x3132332C373031303031323037

问题分析

前两行Test值视觉上完全一致,但SQL将它们判定为不同值,导致COUNTR均为1而非预期的2。从ExtraColumn的二进制值可看出,第二行末尾多了0xA0——这是非断空格(NBSP),SQL默认的TRIM()仅去除普通空格(ASCII 32,即0x20),无法识别并清除非断空格,因此两个字符串长度不同,GROUP BY时被分成两组。

解决方案

1. 针对性替换非断空格

在字符串处理逻辑中增加对非断空格(CHAR(160))的替换,确保所有空格类字符都被清理:

SELECT 
    CleanedTest AS Test,
    COUNT(*) AS COUNTR,
    LEN(CleanedTest) AS LENofTEST,
    DATALENGTH(CleanedTest) AS DataLENofTEST,
    CAST(CleanedTest AS VARBINARY(30)) AS ExtraColumn
FROM
    (SELECT 
         -- 先替换普通空格和非断空格,再执行TRIM
         TRIM(REPLACE(REPLACE(SOS1 + ',' + PANO20, ' ', ''), CHAR(160), '')) AS CleanedTest
     FROM 
         MyServerName.dbo.MyTableName
     WHERE 
         PANO20 LIKE '%701001207%') A
GROUP BY 
    CleanedTest

2. 扩展清理范围(处理更多不可见字符)

如果数据中还存在制表符、换行符等其他不可见字符,可进一步扩展替换逻辑:

SELECT 
    CleanedTest AS Test,
    COUNT(*) AS COUNTR,
    LEN(CleanedTest) AS LENofTEST,
    DATALENGTH(CleanedTest) AS DataLENofTEST,
    CAST(CleanedTest AS VARBINARY(30)) AS ExtraColumn
FROM
    (SELECT 
         TRIM(
             REPLACE(
                 REPLACE(
                     REPLACE(SOS1 + ',' + PANO20, ' ', ''),
                     CHAR(160), ''), -- 非断空格
                 CHAR(9), '') -- 制表符
         ) AS CleanedTest
     FROM 
         MyServerName.dbo.MyTableName
     WHERE 
         PANO20 LIKE '%701001207%') A
GROUP BY 
    CleanedTest

3. 通用清理所有非打印字符(复杂场景)

如果数据存在多种未知非打印字符,可使用递归CTE配合PATINDEX清除所有非可打印字符:

WITH CleanedStrings AS (
    SELECT 
        SOS1 + ',' + PANO20 AS RawString
    FROM MyServerName.dbo.MyTableName
    WHERE PANO20 LIKE '%701001207%'
    UNION ALL
    SELECT 
        REPLACE(RawString, SUBSTRING(RawString, PATINDEX('%[^ -~]%', RawString), 1), '')
    FROM CleanedStrings
    WHERE PATINDEX('%[^ -~]%', RawString) > 0
)
SELECT 
    TRIM(REPLACE(RawString, ' ', '')) AS Test,
    COUNT(*) AS COUNTR,
    LEN(TRIM(REPLACE(RawString, ' ', ''))) AS LENofTEST,
    DATALENGTH(TRIM(REPLACE(RawString, ' ', ''))) AS DataLENofTEST,
    CAST(TRIM(REPLACE(RawString, ' ', '')) AS VARBINARY(30)) AS ExtraColumn
FROM CleanedStrings
WHERE PATINDEX('%[^ -~]%', RawString) = 0
GROUP BY TRIM(REPLACE(RawString, ' ', ''))
OPTION (MAXRECURSION 100)

说明

所有方案核心是统一字符串清理逻辑,确保GROUP BY和SELECT使用完全相同的处理规则,同时覆盖所有可能导致字符串“视觉相同、实际不同”的不可见字符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 01:52:10