Jest to bardzo podobne do innych pytań, ale najlepsze zapytanie jest nadal trudne.
Zapytanie podstawowe aby szybko uzyskać sumę bieżącą:
SELECT to_char(date_trunc('month', date_added), 'Mon YYYY') AS mon_text
, sum(sum(qty)) OVER (ORDER BY date_trunc('month', date_added)) AS running_sum
FROM tbl
GROUP BY date_trunc('month', date_added)
ORDER BY date_trunc('month', date_added);
Trudną częścią jest wypełnienie brakujących miesięcy :
WITH cte AS (
SELECT date_trunc('month', date_added) AS mon, sum(qty) AS mon_sum
FROM tbl
GROUP BY 1
)
SELECT to_char(mon, 'Mon YYYY') AS mon_text
, sum(c.mon_sum) OVER (ORDER BY mon) AS running_sum
FROM (SELECT min(mon) AS min_mon FROM cte) init
, generate_series(init.min_mon, now(), interval '1 month') mon
LEFT JOIN cte c USING (mon)
ORDER BY mon;
niejawny CROSS JOIN LATERAL
wymaga Postgresa 9.3+. Zaczyna się od pierwszego miesiąca w tabeli.
Aby zacząć od danego miesiąca :
WITH cte AS (
SELECT date_trunc('month', date_added) AS mon, sum(qty) AS mon_sum
FROM tbl
GROUP BY 1
)
SELECT to_char(mon, 'Mon YYYY') AS mon_text
, COALESCE(sum(c.mon_sum) OVER (ORDER BY mon), 0) AS running_sum
FROM generate_series('2015-01-01'::date, now(), interval '1 month') mon
LEFT JOIN cte c USING (mon)
ORDER BY mon;
Oddzielenie miesięcy od różnych lat. Nie prosiłeś o to, ale najprawdopodobniej będziesz tego chciał.
Zwróć uwagę, że „miesiąc” w pewnym stopniu zależy od ustawienia strefy czasowej bieżącej sesji! Szczegóły:
Powiązane:
- Obliczanie skumulowanej sumy w PostgreSQL
- PostgreSQL:liczenie wierszy dla zapytania 'w minutach'
- Funkcja okna Postgres i grupuj według wyjątków