SQL Server按c1、c2分组并将c3、c4转为XML的优化实现
按分组生成唯一XML且避免重复的SQL解决方案
背景与问题
假设我们有这样的数据集(可通过以下SQL构造):
select * from (select 'v1_1'c1,'v2_1'c2,'v3_1'c3,'v4_asd'c4 union all select 'v1_1'c1,'v2_1'c2,'v3_2'c3,'v4_fds'c4 union all select 'v1_1'c1,'v2_1'c2,'v3_3'c3,'v4_gfd'c4 union all select 'v1_1'c1,'v2_2'c2,'v3_4'c3,'v4_234'c4 union all select 'v1_1'c1,'v2_2'c2,'v3_5'c3,'v4_654'c4 union all select 'v1_2'c1,'v2_1'c2,'v3_6'c3,'v4_hgf'c4 union all select 'v1_2'c1,'v2_1'c2,'v3_7'c3,'v4_ttr'c4 union all select 'v1_2'c1,'v2_3'c2,'v3_8'c3,'v4_654'c4 union all select 'v1_2'c1,'v2_3'c2,'v3_9'c3,'v4_t54'c4 union all select 'v1_2'c1,'v2_4'c2,'v3_0'c3,'v4_43e'c4) t
我们需要按c1、c2字段分组,把每组对应的c3、c4数据转换成XML格式。但如果直接把数据存入临时表#t后关联生成XML,会出现重复的XML内容,而且不想用主查询distinct或者GROUP BY搭配MAX这类聚合函数来过滤重复值。
可行解决方案
这里有个不需要额外去重或聚合的办法:先获取唯一的c1+c2分组,再针对每个分组生成对应XML:
select *, (select * from #t i1 where t1.c1=i1.c1 and t1.c2=i1.c2 for xml raw) as group_xml from (select distinct c1,c2 from #t) t1
为什么这个方案有效?
- 内层的
select distinct c1,c2 from #t先拿到了所有唯一的分组组合,确保每个c1+c2只出现一次 - 外层查询针对每个唯一分组,通过关联子查询拉取该分组下的所有c3、c4数据并生成XML,这样每个分组只会生成一份对应的XML,完全避免了重复问题
- 整个逻辑简洁直接,不需要额外的去重步骤或者聚合函数,性能也更高效
内容的提问来源于stack exchange,提问作者elle0087
相关产品推荐
相关产品推荐

