如何将SQL Server结果集Rows转换为具有变量Comumn和行

时间:2015-05-21 17:55:36

标签: sql sql-server pivot

我将这些数据从一个视图中获取,内部从各种来源收集,我想以规范化的方式格式化这些数据,因此这可以很容易地在SSRS中用于图表目的。

原始数据

ServerName  TimeStamp               CPU_PCT_Utilization
Server_01   2015-04-16 16:23:04.000 2.781995773
Server_01   2015-04-16 16:28:04.000 2.804701567
Server_01   2015-04-16 17:23:04.000 2.804701567
Server_02   2015-04-21 04:33:02.000 1.094034672
Server_02   2015-04-20 17:28:02.000 1.34284699
Server_02   2015-04-20 17:33:02.000 3.027540922
Server_02   2015-04-20 13:28:03.000 0.860414088
Server_02   2015-04-20 13:33:03.000 0.785780609
Server_02   2015-04-20 18:28:02.000 3.027540922
Server_03   2015-04-21 07:04:57.000 1.316953659
Server_03   2015-04-21 07:09:57.000 1.483076811
Server _??  …   .
Server _??  ..  .
Server _??  .   .
Server _??  .   .

必需的输出

TimeStamp   Server_01   Server_02   Server_03   Server _??  Server _??
2015-04-16 16:23:04.000 2.781995773 NULL    NULL    NULL    .
2015-04-16 16:28:04.000 2.804701567 NULL    NULL    .   …
2015-04-16 17:23:04.000 2.804701567 NULL    NULL    …   .
2015-04-21 04:33:02.000 NULL    1.094034672 NULL    .   .
2015-04-20 17:28:02.000 NULL    1.34284699  NULL    .   …
2015-04-20 17:33:02.000 NULL    3.027540922 NULL    …   NULL
2015-04-20 13:28:03.000 NULL    0.860414088 NULL    .   NULL
2015-04-20 13:33:03.000 NULL    0.785780609 NULL    .   NULL
2015-04-20 18:28:02.000 NULL    3.027540922 NULL    …   NULL
2015-04-21 07:04:57.000 NULL    NULL    1.316953659 .   ..
2015-04-21 07:09:57.000 NULL    NULL    1.483076811 .   .
…   .   …   .   NULL    …
..  .   ..  .   .   …
.   …   NULL    …   .   .
.   .   .   .   …   .

我尝试使用数据透视,但这没有帮助,如果有人可以为此编写查询会很好,这里的行和列都是动态的。

类似的解决方案发布在Simple way to transpose columns and rows in Sql?,但具有固定值。

2 个答案:

答案 0 :(得分:1)

要旋转到列的值不是常量,您必须使用动态SQL ,只需要构建以下语句{/ 1}}:

dynamic sql

要构建上述语句,您可以在上面的模板中选择 distinct 服务器名称为变量:

case ServerName
   when 'Server_n' then CPU_PCT_Utilization
   else null 
end as Server_n

以下是a demo of what I said

MS SQL Server架构设置

declare @CaseStmnt varchar(max)=''
select @CaseStmnt=',case ServerName
when '''+s+''' then CPU_PCT_Utilization
else null 
end as '+s+@CaseStmnt
from (select distinct ServerName s from pvtTbl) q  

<强>查询

create table pvtTbl(ServerName varchar(10), dt datetime,CPU_PCT_Utilization float);
go
insert into pvtTbl values
('Server_01',   '2015-04-16 16:23:04.000', 2.781995773),
('Server_01',   '2015-04-16 16:28:04.000', 2.804701567),
('Server_01',   '2015-04-16 17:23:04.000', 2.804701567),
('Server_02',   '2015-04-21 04:33:02.000', 1.094034672),
('Server_02',   '2015-04-20 17:28:02.000', 1.34284699),
('Server_02',   '2015-04-20 17:33:02.000', 3.027540922),
('Server_02',   '2015-04-20 13:28:03.000', 0.860414088),
('Server_02',   '2015-04-20 13:33:03.000', 0.785780609),
('Server_02',   '2015-04-20 18:28:02.000', 3.027540922),
('Server_03',   '2015-04-21 07:04:57.000', 1.316953659),
('Server_03',   '2015-04-21 07:09:57.000', 1.483076811);

<强>结果:

declare @CaseStmnt varchar(max)=''
select @CaseStmnt=@CaseStmnt+', case ServerName
when '''+s+''' then CPU_PCT_Utilization
else null 
end as '+s
from (select distinct ServerName s from pvtTbl) q 
exec('select dt '+@CaseStmnt+' from pvtTbl')

答案 1 :(得分:0)

你可以创建一个变量@cols并使用带有XML路径的STUFF()函数来构建一个动态的serverName列表,以便像这样传入pivot list运算符:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.ServerName)  
            FROM pvtTbl c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT dt, ' + @cols + ' from 
            (
                select serverName,dt,CPU_PCT_Utilization
                from pvtTbl
           ) x
            pivot 
            (
                 max(CPU_PCT_Utilization)
                for ServerName in (' + @cols + ')
            ) p '


execute(@query)

请参阅下面的SQL小提琴解决方案:

SQL Fiddle Dynamic Pivot Example