2009-03-17 2 views
1

Ich arbeite mit einer MSSQL 2000-Datenbank, die große Mengen von Windows-Perfmon-Daten enthält, die für alle Server in der Umgebung gesammelt wurden. Ich verwende SSRS 2005, um ein benutzerdefiniertes Berichtsdiagramm zu erstellen, um die Messwerte im Zeitverlauf zu visualisieren.Wie kann ich Zeilen zusammenfassen, um die Auflösung von Daten in einer SQL-Abfrage zu reduzieren?

Wenn ich beispielsweise den letzten Monat anzeigen wollte, würde die umfangreiche Anzahl von Datenpunkten einen hässlichen Bericht mit unlesbaren Beschriftungen auf der X-Achse erzeugen. Ich würde gerne die Datenmenge nach Zeit auf n Datenpunkte reduzieren, um den Durchschnittswert über die gruppierten Zeitspannen zu geben.

Ich habe versucht, eine Abfrage mit ausgefallenen GROUP BY-Klauseln zu erstellen, war nicht in der Lage, etwas zu bauen, das ausgeführt wird. Ich dachte, dies sollte eine häufige Aufgabe für SQL sein, aber ich habe keine Antworten online gefunden.

Die Tabellenstruktur sieht im Prinzip wie folgt aus. Dies ist eigentlich die MOM 2005 OnePoint-Datenbank, aber ich denke, die Anwendung ist irrelevant.

CREATE TABLE PerfTable (
    [time] datetime, 
    value float, 
    Server nvarchar(356), 
    ObjectName nvarchar(225), 
    CounterName nvarchar(225), 
    InstanceName nvarchar(225), 
    Scale float 
); 
+0

Versuchen Sie, nach einem bestimmten Zeitintervall zu gruppieren? –

+0

Ein beliebiges Zeitintervall. Ich kann entscheiden, dass 20 Datenpunkte auf dem Diagramm ideal sind, deshalb möchte ich X Datenpunkte auf 20 reduzieren. – spoulson

Antwort

0

Müssen Sie wirklich die Anzahl der von SQL zurückgegebenen Datensätze oder nur die vom Diagramm gerenderten Daten reduzieren?

Es könnte einfacher sein, alle Werte von SQL zu erhalten, und dann die Daten in etwas mehr brauchbare später zu massieren. Durch das Ändern der Abfrage wird die Netzwerkauslastung verringert, da weniger Daten gesendet werden. Wenn dies jedoch nicht von Belang ist, ist die Abfrage möglicherweise nicht der beste Ort dafür.

1

Es könnte sich lohnen, eine View zu erstellen, um Daten im Wert von Monaten zu betrachten und mit SQL dahinter zu arbeiten, um die Datenmenge zu reduzieren.

Dann können Sie den Bericht aus dieser Ansicht ausführen.

Es könnte sich auch lohnen, uns eine Vorstellung von der beteiligten Tabellenstruktur und dem SQL zu geben, das Sie gerade verwenden, um die Ergebnisse zu erhalten.

0

Sie können die DATEPART-Funktion verwenden, um Datenblöcke nach bestimmten Tagen, Stunden oder Minuten (oder mehreren anderen) zu filtern. Sie sollten in der Lage sein, nach diesen zu gruppieren und die benötigten Durchschnittswerte/Aggregate zu erhalten.

OK, hier ist die Lösung n Aggregate (soweit es in jedem Stück von Zeitdaten ist) zu erhalten:

declare @points as int 
declare @start as float 
declare @period as float 

set @points = 20 

select 
@start=cast(min(time) as float), 
@period=cast(max(time)-min(time) as float) 
from perftable 

select avg(value), 
round((cast(time as float)[email protected])/(@period/@points),0,1) 
from perftable 
group by 
round((cast(time as float)[email protected])/(@period/@points),0,1) 

@points Variable eine Zahl od aggregiert Sie erhalten möchten. @start ist an der Zeit des ersten Datensatzes in Bericht @period ist die Differenz zwischen Anfangs- und Enddaten in Bericht

Der Rest ist ziemlich lineare Skalierung der Daten zu schweben gegossen auf einen Bereich [0; @points], Kürzen Ergebnisse zu Ganzzahlen und Gruppierung durch abgeschnittene Ergebnisse.

+0

Ich konnte das machen, aber was ich tun möchte, ist Aggregate bis zu nicht mehr als * n * Datenpunkte. Der Benutzer, der den Bericht generiert, möchte nicht mit den Aggregationsintervallen experimentieren, um ein brauchbares Berichtsdiagramm zu erhalten. – spoulson

0

Angenommen, wir wollen 3 mal und den Durchschnittswert in dieser Zeitspanne haben.

Zuerst bestimmen wir die Punkte .. Start-Ende, Start-Ende, Start-Ende usw. Dies können Sie in Ihrem eigenen Code tun, damit ich Parameter verwenden.

In diesem Beispiel gruppieren wir auch nach 'server', aber Sie können zusätzliche Spalten hinzufügen oder entfernen.

DECLARE @startdate1 as DateTime 
DECLARE @enddate1 as DateTime 
DECLARE @startdate2 as DateTime 
DECLARE @enddate2 as DateTime 
DECLARE @startdate3 as DateTime 
DECLARE @enddate3 as DateTime 
SELECT 
    CASE WHEN time >= @startdate1 AND time < @enddate1 THEN 'PERIOD1' 
    ELSE CASE WHEN time >= @startdate2 AND time < @enddate2 THEN 'PERIOD2' 
    ELSE CASE WHEN time >= @startdate3 AND time < @enddate3 THEN 'PERIOD3' 
    END 
    END 
    END as Period, 
    AVG(p.[value]), 
    p.[Server] 
FROM PerfTable p 
GROUP BY 
    CASE WHEN time >= @startdate1 AND time < @enddate1 THEN 'PERIOD1' 
    ELSE CASE WHEN time >= @startdate2 AND time < @enddate2 THEN 'PERIOD2' 
    ELSE CASE WHEN time >= @startdate3 AND time < @enddate3 THEN 'PERIOD3' 
    END 
    END 
    END, 
    p.[Server] 
0

Ich habe eine Lösung, die genau das ist, wonach ich gefragt habe.Wenn ich zu einer Gruppe von einer Zeiteinheit wollte, es ist ziemlich einfach:

Gruppe von Stunde:

select 
    dateadd(hh, datediff(hh, '1970-01-01', [time]), '1970-01-01'), 
    Server, ObjectName, CounterName, InstanceName, avg(value) 
from PerfTable 
group by 
    dateadd(hh, datediff(hh, '1970-01-01', [time]), '1970-01-01'), 
    ComputerName, ObjectName, CounterName, InstanceName 
order by 
    dateadd(hh, datediff(hh, '1970-01-01', [time]), '1970-01-01') desc, 
    ObjectName, CounterName, InstanceName, ComputerName 

Das betrifft nicht nur die Notwendigkeit, Adresse zu n Datenpunkten zu verringern.