无法在STRING_AGG前用DISTINCT/GROUPING,如何实现SQL去重合并?
问题解答
从A点到B点的SQL操作
从重复的字符串序列(A点)得到唯一值拼接的字符串(B点),核心是提取字符串中的唯一值后重新用分隔符拼接,本质属于字符串去重+聚合操作。
无法使用DISTINCT/GROUPING在STRING_AGG前的解决方案
如果不能直接在STRING_AGG前用DISTINCT或GROUPING,可以通过以下方法实现去重拼接:
方法1:拆分字符串为行后去重再聚合
利用字符串拆分函数(如SQL Server的STRING_SPLIT)将原字符串拆分为单行值,去重后再用STRING_AGG拼接:
SELECT STRING_AGG(value, '/') AS deduplicated_result FROM ( SELECT DISTINCT value FROM STRING_SPLIT('261/261/261/261/262/262/261/262/261/261/261', '/') ) AS split_data
方法2:递归CTE拆分后去重聚合
如果数据库不支持内置拆分函数,用递归CTE拆分字符串,再去重拼接:
WITH split_cte AS ( SELECT CAST('' AS VARCHAR(MAX)) AS segment, CAST('261/261/261/261/262/262/261/262/261/261/261' AS VARCHAR(MAX)) AS rest_str UNION ALL SELECT CAST(LEFT(rest_str, CHARINDEX('/', rest_str + '/') - 1) AS VARCHAR(MAX)), CAST(SUBSTRING(rest_str, CHARINDEX('/', rest_str + '/') + 1, LEN(rest_str)) AS VARCHAR(MAX)) FROM split_cte WHERE rest_str <> '' ) SELECT STRING_AGG(DISTINCT segment, '/') AS deduplicated_result FROM split_cte WHERE segment <> ''
方法3:自定义去重拼接函数
创建自定义函数封装拆分、去重、拼接逻辑,调用时直接传入原字符串和分隔符:
CREATE FUNCTION dbo.DeduplicateStringAgg(@input_str VARCHAR(MAX), @delimiter CHAR(1)) RETURNS VARCHAR(MAX) AS BEGIN DECLARE @result VARCHAR(MAX) = '' DECLARE @temp_table TABLE (value VARCHAR(MAX)) -- 拆分字符串插入临时表 WHILE CHARINDEX(@delimiter, @input_str) > 0 BEGIN INSERT INTO @temp_table VALUES(LEFT(@input_str, CHARINDEX(@delimiter, @input_str) - 1)) SET @input_str = SUBSTRING(@input_str, CHARINDEX(@delimiter, @input_str) + 1, LEN(@input_str)) END INSERT INTO @temp_table VALUES(@input_str) -- 去重后拼接 SELECT @result = STRING_AGG(DISTINCT value, @delimiter) FROM @temp_table RETURN @result END -- 调用函数 SELECT dbo.DeduplicateStringAgg('261/261/261/261/262/262/261/262/261/261/261', '/') AS deduplicated_result
内容的提问来源于stack exchange,提问作者Alex Ker
相关产品推荐
相关产品推荐

