2016-11-23 118 views
0

我有一个表SQL:枢轴上多列

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]) 
+0

只是注意,这是不是一个真正的支点 - 这是一个聚集。数据透视明确地将列中的值转换为新的列。在这种情况下,您可以为每个时期创建列。 –

回答

4

使用条件聚合。值组合成字符串是有点棘手,需要XML逻辑在SQL Server:

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之前对之前的每个行进行聚合。我不确定优化器是否足够好,每个名称只能运行一次子查询。

+2

可能希望按时间段添加按顺序排列的东西查询。 – SqlZim

+0

非常感谢。有用! – anjulis

+1

@SqlZim。 。 。好主意。 –

0

使用组通过与东西功能并获得预期的结果

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