我有一个按以下方式组织的数据集:
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
...
其中 A0001 是项目 #1 的值 A,B0001 是项目 #1 的值 B。一个表可以有60多个不同的项目,每个项目有一个A值列和一个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 以形成索引列的值。另一部分是我以前从未使用过 Pivot,所以我也对基本语法感到困惑。
我认为最终我需要有一个多步骤解决方案,首先将总和构建为:
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) 解决方案必须在 MSSQL 2005 上的 T-SQL 中。
注2) 表格的格式不能更改。
编辑我考虑过的另一种方法在每列上使用 UNION 和单独的 SUM():
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 个不同的表构建相同的查询——所有表的样式都相同。