我有一个按以下方式组织的数据集:
Timestamp|A0001|A0002|A0003|A0004|B0001|B0002|B0003|B0004 ...
---------+-----+-----+-----+-----+-----+-----+-----+-----
2008-1-1 | 1 | 2 | 10 | 6 | 20 | 35 | 300 | 8
2008-1-2 | 5 | 2 | 9 | 3 | 50 | 38 | 290 | 2
2008-1-4 | 7 | 7 | 11 | 0 | 30 | 87 | 350 | 0
2008-1-5 | 1 | 9 | 1 | 0 | 25 | 100 | 10 | 0
...
其中,a001是项目1的值a,b001是项目1的值b。一个表中可以有60多个不同的项目,每个项目都有一个值列和一个B值列,这意味着表中总共有120多个列。
我想得到的是一个3列结果(项目索引、A值、B值),它对每个项目的A值和B值求和:
Index | A Value | B Value
------+---------+--------
0001 | 14 | 125
0002 | 20 | 260
0003 | 31 | 950
0004 | 9 | 10
....
当我从一列转到另一行时,我希望在解决方案中有一个支点,但我不确定如何充实它。部分问题是如何去掉a和b来形成索引列的值。另一部分是,我以前从来没有使用过透视图,所以我也对基本语法感到困惑。
我认为,最终我需要一个多步骤的解决方案,首先将总结构建为:
ColName | Value
--------+------
A0001 | 14
A0002 | 20
A0003 | 31
A0004 | 9
B0001 | 125
B0002 | 260
B0003 | 950
B0004 | 10
然后修改colname数据以去掉索引:
ColName | Value | Index | Aspect
--------+-------+-------+-------
A0001 | 14 | 0001 | A
A0002 | 20 | 0002 | A
A0003 | 31 | 0003 | A
A0004 | 9 | 0004 | A
B0001 | 125 | 0001 | B
B0002 | 260 | 0002 | B
B0003 | 950 | 0003 | B
B0004 | 10 | 0004 | B
最后自我连接,将b值向上移动到a值旁边。
为了得到我想要的东西,这似乎是一个冗长的过程。所以我在寻求建议,无论我是朝着正确的方向前进,还是有另一种方法让我的生活变得如此容易,我已经仔细研究过了。
注1)解决方案必须在MSSQL2005的T-SQL中。
注2)表格的格式不能更改。
编辑
我考虑过的另一种方法是在每一列上使用union和individual sum()s:
SELECT '0001' as Index, SUM(A0001) as A, SUM(B0001) as B FROM TABLE
UNION
SELECT '0002' as Index, SUM(A0002) as A, SUM(B0002) as B FROM TABLE
UNION
SELECT '0003' as Index, SUM(A0003) as A, SUM(B0003) as B FROM TABLE
UNION
SELECT '0004' as Index, SUM(A0004) as A, SUM(B0004) as B FROM TABLE
UNION
...
但这种方法也不太好看
编辑
到目前为止,有两种很好的反应。但我想在查询中再添加两个条件:-)
1)我需要根据时间戳的范围(minv<timestamp<maxv)选择行。
2)我还需要在处理时间戳的UDF上有条件地选择行。
使用Brettski的表名,上面的内容会转换为:
...
(SELECT A0001, A0002, A0003, B0001, B0002, B0003
FROM ptest
WHERE timestamp>minv AND timestamp<maxv AND fn(timestamp)=fnv) p
unpivot
(val for item in (A0001, A0002, A0003, B0001, B0002, B0003)) as unpvt
...
考虑到我已经有条件地添加了fn()需求,我认为我还需要按照jonathon的建议执行动态SQL路径。尤其是当我必须为12个不同的表构建相同的查询时——都是相同的样式。