Ich muss die fortlaufende Summe über einen Zeitraum von 7 Tagen für jede Zeile (1 Zeile pro Tag) erhalten.
Zum Beispiel:
| Date | Count | 7-Day Rolling Sum |
------------------------------------------
| 2016-02-01 | 1 | 1
| 2016-02-02 | 1 | 2
| 2016-02-03 | 2 | 4
| 2016-02-04 | 2 | 6
| 2016-02-05 | 2 | 8
| 2016-02-06 | 2 | 10
| 2016-02-07 | 2 | 12
| 2016-02-08 | 2 | 13 --> here we start summing from 02-02
| 2016-02-09 | 2 | 14 --> here we start summing from 02-03
| 2016-02-10 | 5 | 17 --> here we start summing from 02-04
Ich brauche dies in einer Abfrage, die die Zeilen mit der fortlaufenden 7-Tage-Summe und dem Datum des letzten Tages des Summenbereichs zurückgibt. Beispiel: Tag = 2016-02-10, Summe 17.
Bisher habe ich das, aber es funktioniert nicht vollständig:
DO
$do$
DECLARE
curr_date date;
num bigint;
BEGIN
FOR curr_date IN (SELECT date_trunc('day', d)::date FROM generate_series(CURRENT_DATE-31, CURRENT_DATE-1, '1 day'::interval) d)
LOOP
SELECT curr_date, SUM(count)
FROM generate_series (curr_date-8, curr_date-1, '1 day'::interval) d
LEFT JOIN m.ping AS p ON p.date = d
LEFT JOIN m.ping_type AS pt ON pt.id = p.ping_type_id
LEFT JOIN m.ping_frequency AS pf ON pf.id = p.ping_frequency_id
WHERE
pt.url_slug = 'active' AND
pf.url_slug = 'weekly';
END LOOP;
END
$do$;
Ich verwende PostgreSQL 9.4.5. Es können mehrere Zeilen mit demselben Datum vorhanden sein. Wenn eine Lücke besteht (ein Tag fehlt), wird der Bereich von 7 aufeinander folgenden Tagen weiterhin eingehalten.
postgresql
postgresql-9.4
aggregate
window-functions
josesigna
quelle
quelle
Antworten:
Die mit Abstand sauberste Lösung ist die Verwendung der Fensterfunktion
sum
mitrows between
:Der wichtige Teil besteht darin, den Zeitrahmen in
days
CTE zu generieren und sich diesem anzuschließen, um keine Tage zu verpassen, für die keine Daten vorliegen.Beispiel
Wenn ich beispielsweise in den letzten 14 Tagen einige Testdaten mit 20 Datensätzen erstelle:
Und fügen Sie vorher einen Wert hinzu:
Verwenden Sie dann die obige Abfrage:
Und erhalten Sie die Ergebnisse für den ganzen Monat:
quelle
days
und deshalb gibt es eine Gruppe von incounts
.Endete mit einer FOR-Schleife, einer TEMP-Tabelle und SELECT in der temporären Tabelle, sobald die for-Schleife fertig ist:
Aber ich stelle mir vor, dass es einen saubereren Weg gibt, eine 7-aufeinanderfolgende Rolling-Summe zu machen als diesen.
quelle
Eine rekursive SQL-Abfrage mit einer Tiefe von 7 kann funktionieren, aber ich weiß nicht, wie effizient sie wäre.
Nicht auf Syntax oder ähnliches getestet.
quelle