[英]Convert multiple SQL rows into one row
下午的人很好的堆棧溢出。
我正在嘗試做一些不確定的事情,但我不確定如何利用SQL知識來實現,但是我很清楚自己想要什么,因此希望這對人們有意義。
我有一些如下所示的perfmon磁盤結果:
DatabaseName ObjectName CounterName InstanceName Server Average
DAG1DB01 logicaldisk avg. disk sec/read d:\mountpoints\DAG1DB01 Server1 13.616
DAG1DB01 logicaldisk avg. disk sec/read d:\mountpoints\DAG1DB01 Server2 17.508
DAG1DB01 logicaldisk avg. disk sec/read d:\mountpoints\DAG1DB01 Server3 12.775
DAG1DB01 logicaldisk avg. disk sec/read d:\mountpoints\DAG1DB01 Server4 13.148
DAG1DB01 logicaldisk avg. disk sec/read d:\mountpoints\DAG1DB01 Server5 10.091
這些是基於此查詢的示例行:
SELECT
e14_db.DatabaseName AS [DatabaseName],
d.ObjectName,
d.CounterName,
d.InstanceName,
d.Server,
AVG(Value) * 1000 AS [Average]
FROM E14_Perfmon_MBX AS d
INNER JOIN E14_Databases AS e14_db
ON e14_db.LogFolderPath = d.InstanceName
WHERE d.ObjectName = 'logicaldisk'
AND d.CounterName = 'avg. disk sec/read'
AND d.DateTime > (DATEADD(hh, -4, GETDATE()))
AND d.Value < 1
GROUP BY d.ObjectName, d.CounterName, d.InstanceName, d.Server, e14_db.DatabaseName
ORDER BY e14_db.DatabaseName, d.Server
我想要的是:
DatabaseName ObjectName CounterName InstanceName Server1 Server2 Server3 Server4 Server5
DAG1DB01 logicaldisk avg. disk sec/read d:\mountpoints\DAG1DB01 13.616 17.508 12.775 13.148 10.091
有誰知道我怎么能做到這一點? 基本上將行應用於自己?
如果需要任何澄清,請隨時提出。
謝謝!
PIVOT
運算符設計用於這種情況。 這應該給您您想要的東西:
SELECT DatabaseName,
ObjectName,
CounterName,
InstanceName,
Server1,
Server2,
Server3,
Server4,
Server5
FROM (SELECT
e14_db.DatabaseName AS [DatabaseName],
d.ObjectName,
d.CounterName,
d.InstanceName,
d.[Server],
d.Value * 1000 AS [Value]
FROM E14_Perfmon_MBX AS d
INNER JOIN E14_Databases AS e14_db
ON e14_db.LogFolderPath = d.InstanceName
WHERE d.ObjectName = 'logicaldisk'
AND d.CounterName = 'avg. disk sec/read'
AND d.DateTime > (DATEADD(hh, -4, GETDATE()))
AND d.Value < 1) sub
PIVOT
(
AVG(Value)
FOR [Server] IN ([Server1], [Server2], [Server3], [Server4], [Server5])
) AS PivotTable
以下語句以固定的列數(從1到5)計算每個服務器的獨立平均值:
SELECT e14_db.DatabaseName AS [DatabaseName]
, d.ObjectName, d.CounterName, d.InstanceName
, AVG(CASE WHEN d.Server = 'Server1' THEN Value ELSE NULL END) *1000 AS [Server1]
, AVG(CASE WHEN d.Server = 'Server2' THEN Value ELSE NULL END) *1000 AS [Server2]
, AVG(CASE WHEN d.Server = 'Server3' THEN Value ELSE NULL END) *1000 AS [Server3]
, AVG(CASE WHEN d.Server = 'Server4' THEN Value ELSE NULL END) *1000 AS [Server4]
, AVG(CASE WHEN d.Server = 'Server5' THEN Value ELSE NULL END) *1000 AS [Server5]
FROM E14_Perfmon_MBX AS d
INNER JOIN E14_Databases AS e14_db
ON e14_db.LogFolderPath = d.InstanceName
WHERE d.ObjectName = 'logicaldisk'
AND d.CounterName = 'avg. disk sec/read'
AND d.DateTime > (DATEADD(hh, -4, GETDATE()))
AND d.Value < 1
GROUP BY d.ObjectName, d.CounterName, d.InstanceName, e14_db.DatabaseName
ORDER BY e14_db.DatabaseName
您也可以使用PIVOT
,但是各種SQL 風格都支持此語法。
方法1
declare @Servers varchar(1000) = ''
declare @Query varchar(8000) = ''
select @Servers = ISNULL(QuoteName(Server) + ',', '') + @Servers from MyTable
set @Servers = SUBSTRING(@Servers,0,len(@Servers))
Set @Query = 'Select DatabaseName, obectName, CounterName, InstanceName , ' +
@Servers + ' From
(
Select DatabaseName, obectName, CounterName, InstanceName,
Server, Average from Mytable
)K Pivot
(
max(Average) FOR Server IN (' + @Servers + ')
) AS pvt'
EXEC(@Query)
方法#2
Select DatabaseName, obectName, CounterName, InstanceName , Server1, Server2,
Server3, Server4, Server5
From
(
Select Select DatabaseName, obectName, CounterName, InstanceName,
Server, Average from Mytable FROM Mytable
)K
Pivot
(
Max(Average) FOR Server IN (Server1, Server2, Server3, Server4, Server5)
) AS pvt
嘗試為每個服務器加入一次PERFMON表,如下所示:
FROM E14_Databases AS e14_db
INNER JOIN E14_Perfmon_MBX AS server1
ON e14_db.LogFolderPath = server1.InstanceName
AND server1.Server = 'Server1'
AND server1.ObjectName = 'logicaldisk'
AND server1.CounterName = 'avg. disk sec/read'
AND server1.DateTime > (DATEADD(hh, -4, GETDATE()))
AND server1.Value < 1
INNER JOIN E14_Perfmon_MBX AS server2
ON e14_db.LogFolderPath = server2.InstanceName
AND server2.Server = 'Server2'
AND server2.ObjectName = 'logicaldisk'
AND server2.CounterName = 'avg. disk sec/read'
AND server2.DateTime > (DATEADD(hh, -4, GETDATE()))
AND server2.Value < 1
然后為每個聯接添加一列:
AVG(Server1.Value) * 1000 AS [Server1]
修改表以包含額外的列,並運行更新,其中server ='Server2'
更新d設置server2 =先前服務器條目的值(例如,其中server ='server2')
這樣做是很痛苦的,但是唯一的選擇是不使用SQL語句實際編輯表。
編輯:我建議制作2張桌子,一張帶有所有信息(數據庫名稱等),然后一張帶有分數
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.