为了获得您想要的结果,您必须首先查看取消旋转datacount
和datasum
列,然后应用旋转功能。
数据的反透视将采用多列并返回多行,这将允许使用datatype
值更容易地进行数据轮换。由于您使用的是 SQL Server 2012,因此您可以使用 UNPIVOT 函数轻松取消透视数据,也可以将 CROSS APPLY 与 VALUES 子句一起使用。
select t.datadate, t.timestart, t.timeend,
'type'+cast(t.datatype as varchar(2))+ replace(c.col, 'data', '') as col, c.value
from starttable t
cross apply
(
values ('datacount', datacount), ('datasum', datasum)
) c (col, value);
请参阅演示。这将给出一个包含多个列的结果,并且它还有一个新的计算列,其中包含将被透视的值:
| DATADATE | TIMESTART | TIMEEND | COL | VALUE |
--------------------------------------------------------------------------
| 2013-06-03 | 20:00:00.0000000 | 21:00:00.0000000 | type10count | 3 |
| 2013-06-03 | 20:00:00.0000000 | 21:00:00.0000000 | type10sum | 30 |
| 2013-06-03 | 20:00:00.0000000 | 21:00:00.0000000 | type20count | 3 |
| 2013-06-03 | 20:00:00.0000000 | 21:00:00.0000000 | type20sum | 30 |
然后对这个结果应用 PIVOT:
select datadate, timestart, timeend,
type10count, type10sum, type20count, type20sum, type30count, type30sum
from
(
select t.datadate, t.timestart, t.timeend,
'type'+cast(t.datatype as varchar(2))+ replace(c.col, 'data', '') as col, c.value
from starttable t
cross apply
(
values ('datacount', datacount), ('datasum', datasum)
) c (col, value)
) d
pivot
(
sum(value)
for col in (type10count, type10sum, type20count, type20sum, type30count, type30sum)
) piv;
请参阅带有演示的 SQL Fiddle
现在,如果您有未知数量的datatype
值,那么您可以使用动态 SQL 来获取结果:
DECLARE @cols AS NVARCHAR(MAX),
@colsNull AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME('type'+cast(t.datatype as varchar(2))+c.col)
from starttable t
cross apply
(
values ('count', 1), ('sum', 2)
) c (col, so)
group by t.datatype, c.col, c.so
order by t.datatype, c.so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colsNull = STUFF((SELECT ',isNull(' + QUOTENAME('type'+cast(t.datatype as varchar(2))+c.col)
+', 0) as '+QUOTENAME('type'+cast(t.datatype as varchar(2))+c.col)
from starttable t
cross apply
(
values ('count', 1), ('sum', 2)
) c (col, so)
group by t.datatype, c.col, c.so
order by t.datatype, c.so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT datadate, timestart, timeend,' + @colsNull + '
from
(
select t.datadate, t.timestart, t.timeend,
''type''+cast(t.datatype as varchar(2))+ replace(c.col, ''data'', '''') as col, c.value
from starttable t
cross apply
(
values (''datacount'', datacount), (''datasum'', datasum)
) c (col, value)
) d
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute(@query);
请参阅SQL Fiddle with Demo。两个版本都给出了结果:
| DATADATE | TIMESTART | TIMEEND | TYPE10COUNT | TYPE10SUM | TYPE20COUNT | TYPE20SUM | TYPE30COUNT | TYPE30SUM |
----------------------------------------------------------------------------------------------------------------------------------
| 2013-06-03 | 19:00:00.0000000 | 20:00:00.0000000 | 2 | 20 | 0 | 0 | 0 | 0 |
| 2013-06-03 | 20:00:00.0000000 | 21:00:00.0000000 | 3 | 30 | 3 | 30 | 3 | 30 |