SQL实现多列无序组合等价去重并生成CSV格式输出
问题原因
你现有查询的问题出在子查询中使用了distinct修饰字符值,导致同一行内重复出现的字符被强制去重,例如AAB组合会被错误处理为仅包含A和B两个字符,丢失了重复字符的计数,自然无法正确匹配包含重复字母的等价组合。
正确实现方案
方案1:兼容低版本SQL Server(2016及以下)
沿用你当前的表结构,仅调整拼接逻辑,去掉多余的distinct并增加字符排序保证相同组成的组合拼接结果一致:
-- 生成唯一等价类标识 SELECT DISTINCT STUFF(( SELECT '.' + a.cvalue FROM #t3 a WHERE a.row_num = h.row_num ORDER BY a.cvalue -- 对同一行的三个字符按字母顺序排序,消除排列差异 FOR XML PATH(''), TYPE ).value('.', 'VARCHAR(10)'), 1, 1, '') AS comb FROM #t3 h
如果需要输出CSV格式的等价组合列表,可在此基础上扩展分组拼接逻辑:
SELECT comb AS group_key, STUFF(( SELECT ',' + CONCAT(t2_inner.c1, t2_inner.c2, t2_inner.c3) FROM #t2 t2_inner WHERE STUFF(( SELECT '.' + cvalue FROM #t3 t3_inner WHERE t3_inner.row_num = t2_inner.row_num ORDER BY cvalue FOR XML PATH(''), TYPE ).value('.', 'VARCHAR(10)') = t.comb FOR XML PATH(''), TYPE ).value('.', 'VARCHAR(MAX)'), 1, 1, '') AS equivalent_combinations FROM ( SELECT DISTINCT STUFF(( SELECT '.' + a.cvalue FROM #t3 a WHERE a.row_num = h.row_num ORDER BY a.cvalue FOR XML PATH(''), TYPE ).value('.', 'VARCHAR(10)'), 1, 1, '') AS comb FROM #t3 h ) t
方案2:SQL Server 2017及以上版本简化实现
使用原生STRING_AGG函数,代码更简洁高效:
-- 直接生成等价类与对应CSV组合列表 SELECT group_key, STRING_AGG(raw_combination, ',') AS equivalent_combinations FROM ( SELECT t3.row_num, CONCAT(t2.c1, t2.c2, t2.c3) AS raw_combination, STRING_AGG(t3.cvalue, '.') WITHIN GROUP (ORDER BY t3.cvalue) AS group_key FROM #t3 t3 JOIN #t2 t2 ON t3.row_num = t2.row_num GROUP BY t3.row_num, CONCAT(t2.c1, t2.c2, t2.c3) ) t GROUP BY group_key
以上方案均可正确识别AAB=ABA=BAA这类包含重复字符的等价组合,输出结果完全符合需求。
内容的提问来源于stack exchange,提问作者Hoon Choi
相关产品推荐
相关产品推荐

