Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

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

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von knabnetaD, 30 Oktober 2012.

  1. knabnetaD

    knabnetaD Benutzer

    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!
     
  2. ukulele

    ukulele Datenbank-Guru

    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.
     
  3. knabnetaD

    knabnetaD Benutzer

    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?
     
  4. Tommi

    Tommi Datenbank-Guru

    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:
    http://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
     
  5. knabnetaD

    knabnetaD Benutzer

    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?
     
  6. Tommi

    Tommi Datenbank-Guru

    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:

    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
     
  7. Tommi

    Tommi Datenbank-Guru

    OK, die Darstellung der Tabelle hat jetzt nicht so gut funktioniert. Ich mach das mal grad anders :)
     
  8. Tommi

    Tommi Datenbank-Guru

    So, jetzt mal als Bildchen :)
     

    Anhänge:

  9. ukulele

    ukulele Datenbank-Guru

Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden