我有一个以下列方式组织的数据集:
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以形成Index列的值.另一部分是我以前从未使用过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 ...
但这种方法看起来也不是很好
编辑 到目前为止有2个很棒的回复.但我想在查询中添加两个条件:-)
1)我需要根据一系列时间戳(minv 2)我还需要有条件地选择处理时间戳的UDF上的行 使用Brettski的表名,将以上翻译为: 鉴于我有条件地添加了fn()要求,我认为我还需要按照Jonathon提出的动态SQL路径.特别是因为我必须为12个不同的表构建相同的查询 - 所有相同的样式. 这里回答相同,这很有趣: 您不需要在此列中对列名进行硬编码....
(SELECT A0001, A0002, A0003, B0001, B0002, B0003
FROM ptest
WHERE timestamp>minv AND timestamp
1> Jonathan DeM..:-- Get column names from system table
DECLARE @phCols NVARCHAR(2000)
SELECT @phCols = COALESCE(@phCols + ',[' + name + ']', '[' + name + ']')
FROM syscolumns WHERE id = (select id from sysobjects where name = 'Test' and type='U')
-- Get rid of the column we don't want
SELECT @phCols = REPLACE(@phCols, '[Timestamp],', '')
-- Query & sum using the dynamic column names
DECLARE @exec nvarchar(2000)
SELECT @exec =
'
select
SUBSTRING([Value], 2, LEN([Value]) - 1) as [Index],
SUM(CASE WHEN (LEFT([Value], 1) = ''A'') THEN Cols ELSE 0 END) as AValue,
SUM(CASE WHEN (LEFT([Value], 1) = ''B'') THEN Cols ELSE 0 END) as BValue
FROM
(
select *
from (select ' + @phCols + ' from Test) as t
unpivot (Cols FOR [Value] in (' + @phCols + ')) as p
) _temp
GROUP BY SUBSTRING([Value], 2, LEN([Value]) - 1)
'
EXECUTE(@exec)