Gruppierung von MySQL datetime in Intervallen unabhängig von der Zeitzone

8

Diese Frage wurde before Aber ich stehe vor einem etwas anderen Problem.

Ich habe eine Tabelle, die Ereignisse protokolliert und ihre Zeitstempel speichert (als Datetime). Ich muss in der Lage sein, Zeit in Stücke aufzuteilen und Anzahl von Ereignissen zu erhalten, die in diesem Intervall auftraten. Das Intervall kann benutzerdefiniert sein (Sagen Sie von 5 Minuten bis 1 Stunde und sogar darüber hinaus).

Die offensichtliche Lösung besteht darin, die Datetime in unix_timestamp zu konvertieren und sie durch die Anzahl der Sekunden im Intervall zu dividieren, ihre Floor-Funktion zu übernehmen und sie mit der Anzahl der Sekunden zu multiplizieren. Konvertieren Sie den unix_timestamp schließlich zurück in das Datetime-Format.

Dies funktioniert gut für kleine Intervalle.

%Vor%

Dies gibt die korrekte Ausgabe

%Vor%

Aber wenn ich das Intervall auf 1 Stunde (3600 sec) verlängere

%Vor%

Der Grund, soweit ich das beurteilen konnte, ist, dass unix_timestamp die Zeit von meiner lokalen Zeitzone (GMT + 0530) in UTC konvertiert und dann den numerischen Wert ausgibt.

Ein Wert wie 2012-08-03 00:00:00 wird 2012-08-02 18:30:00 sein. Durch Teilen und Verwenden von floor wird der Minuten-Teil auf 00 gesetzt. Aber wenn ich from_unxtime verwende, wird es wieder in GMT + 0530 konvertiert und gibt mir Intervalle, die bei 30 Minuten beginnen.

Wie stelle ich sicher, dass die Abfrage unabhängig von der Zeitzone korrekt funktioniert? Ich benutze MySQL 5.1.52, so dass to_seconds () nicht verfügbar ist

BEARBEITEN: Die Abfrage sollte auch unabhängig vom Intervall korrekt ausgeführt werden (können Stunden, Minuten, Tage sein). Eine generische Lösung wäre wünschenswert

    
RedBaron 03.08.2012, 05:33
quelle

2 Antworten

7

Sie können TIMESTAMPDIFF verwenden Gruppe nach Zeitintervallen:

Für ein bestimmtes Zeitintervall können Sie Folgendes verwenden:

%Vor%

Ersetzen Sie das Vorkommen von 2012-08-03 00:00:00 durch Ihr minimales Eingabedatum.

<n> ist das angegebene Intervall in Stunden (alle 2 Stunden, 3 Stunden usw.), und Sie können dasselbe für Minuten tun:

%Vor%

Dabei ist <n> das angegebene Intervall in Minuten (alle 45 Minuten, 90 Minuten usw.).

Stellen Sie sicher, dass Sie Ihr minimales Eingabedatum (in diesem Beispiel 2012-08-03 00:00:00 ) als zweiten Parameter an TIMESTAMPDIFF übergeben.

BEARBEITEN: Wenn Sie sich nicht darum kümmern wollen, welche Intervalleinheit in der Funktion TIMESTAMPDIFF ausgewählt werden soll, dann tun Sie das Intervall natürlich nur um Sekunden ( 300 = 5 Minuten, 3600 = 1 Stunde, 7200 = 2 Stunden usw.)

%Vor%

EDIT2: Um Ihren Kommentar bezüglich der Reduzierung der Anzahl von Bereichen in der Anweisung, in der Sie Ihr minimales Parameterdatum übergeben müssen, anzusprechen, können Sie Folgendes verwenden:

%Vor%

Und geben Sie einfach Ihren minimalen Datetime-Parameter einmal in den Join-Subselect ein.

Sie können sogar eine zweite Spalte im join subselect für Ihr Sekundenintervall erstellen (zB 3600 ) und die Spalte so benennen wie secinterval ... und dann die <n> in b.secinterval ändern, also Sie müssen nur Ihren minimalen Datumsparameter AND interval jeweils einmal eingeben.

SQLFiddle-Demo

    
Zane Bien 03.08.2012, 06:06
quelle
1

Die einfachere Methode wäre:

Methode 1

%Vor%

Wenn Sie Ihren ursprünglichen Ansatz verwenden möchten.

Methode2

%Vor%

EDIT1

für die erste Methode, erlaubt es dem Benutzer auch, verschiedene Intervalle zu setzen. Beispiel: Wenn der Benutzer das Protokoll nach 15 Minuten gruppieren möchte,

%Vor%     
lucemia 03.08.2012 05:53
quelle

Tags und Links