SQL:在多个列上进行透视

时间:2016-11-23 15:21:51

标签: sql sql-server

我有一张桌子

Name |  Period |  Value1 |  Value2
-----+---------+---------+-------
 A       1        2        3
 A       2        5        4
 A       3        6        7
 B       1        2        3
 B       2        5        4
 B       3        6        7

我需要像

这样的结果
Name | Value1 |  Value2
-----+--------+------
 A   | 2,5,6  |  3,4,7
 B   | 2,5,6  |  3,4,7

句号的数量是动态的,但我知道如何处理它,所以为简单起见,假设有3个句号

下面的查询为我提供了Value1的结果。我怎样才能得到两者的结果? 我总是可以单独完成它们,然后进行连接,但表格非常大,我需要“合并”四个值,而不是两个。我可以在一份声明中这样做吗?

SELECT Name,
[1]+','+ [2] + ','+ [3]  ValueString
FROM   (
 select  Name,  period,   cpr from #MyTable     
 ) as s     
  PIVOT(SUM(Value1)        
   FOR period IN ([1],[2],[3])

2 个答案:

答案 0 :(得分:4)

使用条件聚合。将值组合到字符串中有点棘手,需要SQL Server中的XML逻辑:

select n.name,
       stuff((select ',' + cast(value1 as varchar(max))
              from t
              where n.name = t.name
              order by t.period
              for xml path ('')
             ), 1, 1, ''
            ) as values1,
       stuff((select ',' + cast(value2 as varchar(max))
              from t
              where n.name = t.name
              order by t.period
              for xml path ('')
             ), 1, 1, ''
            ) as values2
from (select distinct name
      from t
     ) n;

您的值看起来像数字,因此显式转换和缺乏对XML特殊字符的关注。

您可能会问为什么这会在子查询中而不是在外部查询中执行distinct。如果在外部查询中完成,那么SQL引擎可能会在执行distinct之前为每行执行聚合。我不确定优化器是否足够好每个名称只运行一次子查询。

答案 1 :(得分:0)

使用Group By with stuff函数并获得预期结果

SELECT Name ,  STUFF((SELECT ',' + CAST(Value1 AS VARCHAR) FROM #MyTable T2 WHERE T1.Name = T2.Name FOR XML PATH('')),1,1,'') Value1
        ,  STUFF((SELECT ',' + CAST(Value2 AS VARCHAR) FROM #MyTable T3 WHERE T1.Name = T3.Name FOR XML PATH('')),1,1,'') Value2 FROM #MyTable T1 GROUP BY Name