MS SQL Server SQL查询需求:按关联键合并逗号分隔行
解决MS SQL Server中同一Code下关联Key的合并问题
要实现同一Code下合并所有关联Key(只要两组Key存在重叠值就归为同一组),无关联Key单独保留的需求,核心是识别Key的连通分量(互相连通的Key集合),再对每个分量合并Key。以下是具体实现方案:
假设表结构与示例数据
先定义测试用的表和数据:
CREATE TABLE YourTable ( Code VARCHAR(10), Keys VARCHAR(100) ); INSERT INTO YourTable VALUES ('ABC', '100,200'), ('ABC', '200,300'), ('ABC', '500,300'), ('ABC', '700,800'), ('XYZ', '900,1000');
完整SQL解决方案
WITH SplitKeys AS ( -- 1. 拆分逗号分隔的Keys为单个Key值,去除可能的空格 SELECT Code, TRIM(value) AS KeyVal FROM YourTable CROSS APPLY STRING_SPLIT(Keys, ',') ), ConnectedGroups AS ( -- 2. 递归CTE识别同一Code下的连通Key组 -- 初始化:每个Key作为自己的根节点 SELECT Code, KeyVal AS RootKey, KeyVal FROM SplitKeys UNION ALL -- 递归:找到所有与当前Key连通的其他Key,加入同一根组 SELECT sk.Code, cg.RootKey, sk.KeyVal FROM ConnectedGroups cg JOIN SplitKeys sk ON cg.Code = sk.Code JOIN YourTable yt ON sk.Code = yt.Code AND CHARINDEX(',' + cg.KeyVal + ',', ',' + yt.Keys + ',') > 0 AND CHARINDEX(',' + sk.KeyVal + ',', ',' + yt.Keys + ',') > 0 WHERE sk.KeyVal NOT IN ( SELECT KeyVal FROM ConnectedGroups WHERE Code = cg.Code AND RootKey = cg.RootKey ) ), GroupedKeys AS ( -- 3. 按Code和根节点分组,合并去重后的Key值 SELECT Code, RootKey, STRING_AGG(DISTINCT KeyVal, ',') WITHIN GROUP (ORDER BY KeyVal) AS MergedKeys FROM ConnectedGroups GROUP BY Code, RootKey ), FinalGroups AS ( -- 4. 去重同一Code下重复的合并组 SELECT DISTINCT Code, MergedKeys FROM GroupedKeys ) SELECT * FROM FinalGroups;
关键逻辑说明
- SplitKeys:通过
STRING_SPLIT将每行的Key字符串拆分为单个Key记录,方便后续关联判断。 - ConnectedGroups:递归遍历同一Code下的Key,只要两个Key出现在同一行的Keys中,就归为同一连通组,最终收集所有互相连通的Key。
- GroupedKeys:对每个连通组去重,并用
STRING_AGG合并为逗号分隔的字符串,排序保证结果整齐。 - FinalGroups:去除同一Code下重复的合并组(不同根节点可能对应相同的合并结果)。
示例输出
| Code | MergedKeys |
|---|---|
| ABC | 100,200,300,500 |
| ABC | 700,800 |
| XYZ | 900,1000 |
内容的提问来源于stack exchange,提问作者Bala
相关产品推荐
相关产品推荐

