如何将 SQL 服务器结果集行转换为具有变量列和行的列
How to convert SQL server result set Rows to Column with variable Comumn and rows
我正在将这些数据从内部从各种来源收集的一个视图中获取,我想以规范化的方式格式化这些数据,以便在 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 … . .
. . . . … .
我试过使用 pivot 但没有用,如果有人能为此编写查询就太好了,这里的行和列都是动态的。
Simple way to transpose columns and rows in Sql? 上发布了类似的解决方案,但具有固定值。
要旋转到列的值不是常量,您必须使用 动态 SQL,您需要 dynamic sql
来构建以下语句:
case ServerName
when 'Server_n' then CPU_PCT_Utilization
else null
end as Server_n
为了构建上面的语句,你可以 select distinct 上面模板中的服务器名称到一个变量中:
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
MS SQL 服务器架构设置:
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')
结果:
| dt | Server_01 | Server_02 | Server_03 |
|-------------------------|-------------|-------------|-------------|
| April, 16 2015 16:23:04 | 2.781995773 | (null) | (null) |
| April, 16 2015 16:28:04 | 2.804701567 | (null) | (null) |
| April, 16 2015 17:23:04 | 2.804701567 | (null) | (null) |
| April, 21 2015 04:33:02 | (null) | 1.094034672 | (null) |
| April, 20 2015 17:28:02 | (null) | 1.34284699 | (null) |
| April, 20 2015 17:33:02 | (null) | 3.027540922 | (null) |
| April, 20 2015 13:28:03 | (null) | 0.860414088 | (null) |
| April, 20 2015 13:33:03 | (null) | 0.785780609 | (null) |
| April, 20 2015 18:28:02 | (null) | 3.027540922 | (null) |
| April, 21 2015 07:04:57 | (null) | (null) | 1.316953659 |
| April, 21 2015 07:09:57 | (null) | (null) | 1.483076811 |
您可以创建一个变量 @cols
并使用带有 XML 路径的 STUFF()
函数来构建 serverName 的动态列表以传入数据透视列表运算符,如下所示:
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)
请参考下面的SQLFiddle解决方案:
我正在将这些数据从内部从各种来源收集的一个视图中获取,我想以规范化的方式格式化这些数据,以便在 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 … . .
. . . . … .
我试过使用 pivot 但没有用,如果有人能为此编写查询就太好了,这里的行和列都是动态的。
Simple way to transpose columns and rows in Sql? 上发布了类似的解决方案,但具有固定值。
要旋转到列的值不是常量,您必须使用 动态 SQL,您需要 dynamic sql
来构建以下语句:
case ServerName
when 'Server_n' then CPU_PCT_Utilization
else null
end as Server_n
为了构建上面的语句,你可以 select distinct 上面模板中的服务器名称到一个变量中:
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
MS SQL 服务器架构设置:
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')
结果:
| dt | Server_01 | Server_02 | Server_03 |
|-------------------------|-------------|-------------|-------------|
| April, 16 2015 16:23:04 | 2.781995773 | (null) | (null) |
| April, 16 2015 16:28:04 | 2.804701567 | (null) | (null) |
| April, 16 2015 17:23:04 | 2.804701567 | (null) | (null) |
| April, 21 2015 04:33:02 | (null) | 1.094034672 | (null) |
| April, 20 2015 17:28:02 | (null) | 1.34284699 | (null) |
| April, 20 2015 17:33:02 | (null) | 3.027540922 | (null) |
| April, 20 2015 13:28:03 | (null) | 0.860414088 | (null) |
| April, 20 2015 13:33:03 | (null) | 0.785780609 | (null) |
| April, 20 2015 18:28:02 | (null) | 3.027540922 | (null) |
| April, 21 2015 07:04:57 | (null) | (null) | 1.316953659 |
| April, 21 2015 07:09:57 | (null) | (null) | 1.483076811 |
您可以创建一个变量 @cols
并使用带有 XML 路径的 STUFF()
函数来构建 serverName 的动态列表以传入数据透视列表运算符,如下所示:
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)
请参考下面的SQLFiddle解决方案: