Mit DATEADD, DATEDIFF auf 2;3;4;... Minuten runden

knabnetaD

Benutzer
Beiträge
12
Hallo zusammen,
sollte nun die letzte Frage für heute sein :D.

Mit dem Statement
Code:
group by DATEADD(MINUTE, DATEDIFF(MINUTE, 0, start_time), 0)
kann ich mir ja die Datensätze einer Minute zusammenfassen lassen.

Ist es durch Modifikation des Statements möglich, sich auch die Datensätze im 5 Minuten Intervall zusammenfassen zu lassen?
Oder muss ich dafür was ganz anders machen?

Bin mir auch sicher das man die Lösung beim googlen findet, habe aber leider nichts passendes gefunden. Also sorry wenns das schonmal gab. Könnt ja dann den Link posten...

Danke!
 
Werbung:

ukulele

Datenbank-Guru
Beiträge
4.394
Code:
group by DATEADD(MINUTE, DATEDIFF(MINUTE, 0, start_time)/2*2, 0)
würde z.B. nach 2 Minuten Intervallen gruppieren. Das müsste sich fortsetzen lassen.
 

knabnetaD

Benutzer
Beiträge
12
edit: leider zu früh gefreut

Ich wollte mir jetzt folgende Query basteln:
Code:
SELECT    blablabla
FROM      usw. usf.
WHERE    (hosts = @Host) AND (start_time >= @from) AND (end_time <= @to)
GROUP BY DATEADD(@Intervallart, DATEDIFF(@Intervallart, 0, start_time) / @Intervalllänge * @Intervalllänge, 0)
ORDER BY start_time

Über @Host wird ein int-Wert für die Host-ID übergeben - kein Problem
Über @to wird ein DATETIME übergeben - kein Problem
Über @from wird ein DATETIME übergeben - kein Problem
Über @Intervalllänge wird ein INteger übergeben - kein Problem

Über @Intervallart wird ein Text übergeben (entweder MINUTE, HOUR, DAY, WEEK, MONTH oder YEAR je nach dem was man auswählt). - Visual Studio sagt, dass ich dort keine Variable einfügen kann.

Kann ich den Fehler irgendwie umgehen?
Oder muss ich mir eine komplett ander Lösung bauen?
 

Tommi

Datenbank-Guru
Beiträge
284
Hi,

diese Meldung wirst du auch vom SQL-Server bekommen. Die Art des Intervalls in dieser Funktion kann nicht über einen Parameter abgebildet werden!
Hier mußt du so vorgehen, dass du eine feste Intervall-Art vorgibst (z.B. Minute) und alle anderen Intervalle entsprechend umrechnest (Stunde = 60 Min, Tag = 1440 Min usw.)

Alternative ist die Nutzung einer CASE...WHEN...THEN Auswertung für jede Intervall-Art

Im Übrigen verweise ich noch einmal auf folgenden Thread, in dem du diese Frage ähnlich gestellt hast:
https://www.datenbankforum.com/threads/granularität-in-query-festlegen.841/

Hier habe ich auch ein Beispiel angegeben, mit den Intervall-Längen über einen Parameter gesteuert zusammengefasst werden können.

Viele Grüße,
Tommi
 

knabnetaD

Benutzer
Beiträge
12
Ja, deine Lösung habe ich gesehen, aber nicht wirklich verstanden.

Ich würde es ja sehr gerne mit Case-when-then-else umsetzen,
klappt aber leider auch nicht :(

Code:
SELECT    ...
FROM        ...
WHERE    ...
 
CASE @Intervallart
    WHEN '1' THEN 'GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, servicechecks.start_time) / @Intervalllänge * @Intervalllänge, 0)'
    WHEN '2' THEN 'GROUP BY DATEADD(HOUR, DATEDIFF(HOUR, 0, servicechecks.start_time) / @Intervalllänge * @Intervalllänge, 0)'
    WHEN '3' THEN 'GROUP BY DATEADD(DAY, DATEDIFF(DAY, 0, servicechecks.start_time) / @Intervalllänge * @Intervalllänge, 0)'
    WHEN '4' THEN 'GROUP BY DATEADD(WEEK, DATEDIFF(WEEK, 0, servicechecks.start_time) / @Intervalllänge * @Intervalllänge, 0)'
    WHEN '5' THEN 'GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, servicechecks.start_time) / @Intervalllänge * @Intervalllänge, 0)'
    ELSE 'GROUP BY DATEADD(YEAR, DATEDIFF(YEAR, 0, servicechecks.start_time) / @Intervalllänge * @Intervalllänge, 0)'
END
 
ORDER BY start_time

@Intervallart ist ein Integer und kann per Drop-Down-Menü nur die Werte 1-6 annehmen.

Bekomme dann "Incorrect syntax near the keyword 'CASE'.".

Beim ORDER BY bekomme ich ein "Expecting Conversation".
Wenn ich das END wegnehme ist der Fehler beim ORDER BY weg.
Aber das ist ja auch nicht korrekt, oder?
 

Tommi

Datenbank-Guru
Beiträge
284
Hi,

die CASE...WHEN...THEN Anweisung mußt du etwas anders aufbauen.
Das sähe dann wie folgt aus:

Code:
 ...
GROUP BY (CASE WHEN  @Intervallart='YEAR' THEN DATEADD(year, DATEDIFF(year, 0, start_time) / @Intervalllänge * @Intervalllänge, 0)
    WHEN  @Intervallart='MONTH' THEN DATEADD(month, DATEDIFF(month, 0, start_time) / @Intervalllänge * @Intervalllänge, 0)
    WHEN  @Intervallart='DAY' THEN DATEADD(day, DATEDIFF(day, 0, start_time) / @Intervalllänge * @Intervalllänge, 0)
    WHEN  @Intervallart='HOUR' THEN DATEADD(hour, DATEDIFF(hour, 0, start_time) / @Intervalllänge * @Intervalllänge, 0)
    WHEN  @Intervallart='MINUTE' THEN DATEADD(minute, DATEDIFF(minute, 0, start_time) / @Intervalllänge * @Intervalllänge, 0)
    WHEN  @Intervallart='SECOND' THEN DATEADD(second, DATEDIFF(second, 0, start_time) / @Intervalllänge * @Intervalllänge, 0)
  ELSE DATEADD(minute, DATEDIFF(minute, 0, start_time) / @Intervalllänge * @Intervalllänge, 0) END)

Du darfst immer gerne nachfragen, wenn du etwas nicht verstehst. Ich sitze nicht auf meinem Know-How und gebe gerne was weiter.
Ich gebe auch gerne zu, dass meine Erklärungen manchmal sicher etwas "erklärungsbedürftig" (weil nicht gut formuliert) sind.

In dem anderen Thread habe ich ja die Funktion "FLOOR" benutzt. Diese ist wie folgt erklärt:

Gibt die größte ganze Zahl zurück, die kleiner oder gleich der angegebenen Gleitkommazahl mit doppelter Genauigkeit ist.

Klingt komplizierter als es ist. Das besagt nur, dass diese mathematische Funktion einen Ganzzahl-Wert aus einer Division zurückgibt.
Die Funktion ist letztendlich nur eine Rundungs-Funktion. Wenn ich also 5 / 3 rechne, ergäbe das einen Wert von 1,67.
Die Funktion FLOOR(5/3) gibt dann den immer abgerundeten Wert wieder, in diesem Falle also 1.

Dieses Verhalten nutze ich in Bezug auf Zeitdifferenzen in Bezug zu einem Start-Wert.
Ich ermittle also die Zeitdifferenz zwischen der Start-Zeit und dem Eintrag im Datensatz. Diesen Teile ich dann durch das gewünschte Zusammenfassungs-Intervall (In meinem Beispiel sind hier Minuten fest definiert). Da die Floor-Funktion das Divisions-Ergebnis immer abrundet, erhalte ich immer den gleichen Wert in Bezug zum Intervall.

Beispiel:
Startzeit ist 16:00 Uhr, Intervall sind 5 Minuten
Mit folgender Tabelle wird das Verhalten und die Zusammenfassung von FLOOR dann deutlich: (MDS = Minuten-Differenz zur Start-Zeit, IV = Intervall)
Zeit<tab>MDS MDS/IV FLOOR
16:01 1 1/5 = 0.2 0
16:04 4 4/5 = 0,8 0
16:06 6 6/5 = 1,2 1
16:07 7 7/5 = 1,4 1
16:09 9 9/5 = 1,8 1
16:10 10 10/5 = 2 2
16:12 12 12/5 = 2,4 2

Über die Spalte FLOOR kann man also nun eine Gruppierung in 5-Minuten-Intervallen vornehmen, abhängig von der Startzeit und der betrachteten Zeit im Datensatz.

Viele Grüße,
Tommi
 

Tommi

Datenbank-Guru
Beiträge
284
OK, die Darstellung der Tabelle hat jetzt nicht so gut funktioniert. Ich mach das mal grad anders :)
 
Werbung:
Oben