SQL Server,按xml分组

时间:2018-01-17 15:53:34

标签: sql sql-server xml

我有一个类似

的数据集
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分组,并在xml上有c3,c4。

我试过

select *
into #t
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


select 
    *,
    (select c3, c4 
     from #t t2 
     where t.c2 = t2.c2 
       and t.c1 = t2.c1 
     for xml path(''))
from 
    #t t

但我希望不要在group by中使用distinct或max来保留一个值。

我使用了这个解决方案

select *,
       (select * from #t i1 where t1.c1=i1.c1 and t1.c2=i1.c2 for xml raw)
from (select distinct c1,c2 from #t) t1

而是创建多个xml并将它们分组,我在键之前区分并且只需要创建xml

1 个答案:

答案 0 :(得分:0)

使用GROUP BY可以避免DISTINCT无法将XML作为类型列返回(并且对于较大的集合而言速度相当慢)。

SELECT
     a.c1
    ,a.c2
    ,(
        SELECT b.c3
              ,b.c4
        FROM #t AS b
        WHERE a.c1 = b.c1
          AND a.c2 = b.c2
        FOR XML PATH(''),TYPE
    )
FROM #t AS a
GROUP BY a.c1, a.c2

结果

c1      c2      TheXML
v1_1    v2_1    <c3>v3_1</c3><c4>v4_asd</c4><c3>v3_2</c3><c4>v4_fds</c4><c3>v3_3</c3><c4>v4_gfd</c4>
v1_1    v2_2    <c3>v3_4</c3><c4>v4_234</c4><c3>v3_5</c3><c4>v4_654</c4>
v1_2    v2_1    <c3>v3_6</c3><c4>v4_hgf</c4><c3>v3_7</c3><c4>v4_ttr</c4>
v1_2    v2_3    <c3>v3_8</c3><c4>v4_654</c4><c3>v3_9</c3><c4>v4_t54</c4>
v1_2    v2_4    <c3>v3_0</c3><c4>v4_43e</c4>

对于c1和c2上的索引,这应该非常快。