SQL:枢轴上多列
问题描述:
我有一个表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])
答
使用条件聚合。值组合成字符串是有点棘手,需要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
之前对之前的每个行进行聚合。我不确定优化器是否足够好,每个名称只能运行一次子查询。
答
使用组通过与东西功能并获得预期的结果
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
只是注意,这是不是一个真正的支点 - 这是一个聚集。数据透视明确地将列中的值转换为新的列。在这种情况下,您可以为每个时期创建列。 –