PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Gruppieren nach Datenintervallen

WITH t AS (
   SELECT ts, (random()*100)::int AS bandwidth
   FROM   generate_series('2012-09-01', '2012-09-04', '1 minute'::interval) ts
   )

SELECT date_trunc('hour', ts) AS hour_stump
      ,(extract(minute FROM ts)::int / 15) AS min15_slot
      ,count(*) AS rows_in_timeslice               -- optional
      ,sum(bandwidth) AS sum_bandwidth
FROM   t
WHERE  ts >= '2012-09-02 00:00:00+02'::timestamptz -- user's time range
AND    ts <  '2012-09-03 00:00:00+02'::timestamptz -- careful with borders 
GROUP  BY 1, 2
ORDER  BY 1, 2;

Der CTE t stellt Daten bereit, die Ihre Tabelle enthalten könnte:einen Zeitstempel ts pro Minute mit einer bandwidth Anzahl. (Sie brauchen diesen Teil nicht, Sie arbeiten stattdessen mit Ihrer Tabelle.)

Hier ist eine sehr ähnliche Lösung für eine sehr ähnliche Frage – mit detaillierter Erklärung, wie diese spezielle Aggregation funktioniert:

  • date_trunc 5-Minuten-Intervall in PostgreSQL

Hier ist eine ähnliche Lösung für eine ähnliche Frage zum Laufen Summen - mit ausführlicher Erklärung und Links zu den verschiedenen verwendeten Funktionen:

  • PostgreSQL:Laufende Anzahl von Zeilen für eine Abfrage 'pro Minute'

Zusätzliche Frage im Kommentar

WITH -- same as above ...

SELECT DISTINCT ON (1,2)
       date_trunc('hour', ts) AS hour_stump
      ,(extract(minute FROM ts)::int / 15) AS min15_slot
      ,bandwidth AS bandwith_sample_at_min15
FROM   t
WHERE  ts >= '2012-09-02 00:00:00+02'::timestamptz
AND    ts <  '2012-09-03 00:00:00+02'::timestamptz
ORDER  BY 1, 2, ts DESC;

Ruft eine ab nicht aggregierte Stichprobe pro 15-Minuten-Intervall - aus der letzten verfügbaren Zeile im Fenster. Dies wird die 15. Minute sein, wenn die Reihe nicht fehlt. Entscheidende Teile sind DISTINCT ON und ORDER BY .
Weitere Informationen zur verwendeten Technik hier:

  • Erste Zeile in jeder GROUP BY-Gruppe auswählen?