È molto simile ad altre domande, ma la query migliore è comunque complicata.
Query di base per ottenere rapidamente la somma parziale:
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);
La parte difficile è compilare i mesi mancanti :
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;
Il implicito CROSS JOIN LATERAL
richiede Postgres 9.3+. Questo inizia con il primo mese nella tabella.
Per iniziare con un determinato mese :
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;
Mantenendo mesi di anni diversi a parte. Non l'hai chiesto tu, ma molto probabilmente lo vorrai.
Nota che il "mese" in una certa misura dipende dall'impostazione del fuso orario della sessione corrente! Dettagli:
Correlati:
- Calcolo della somma cumulativa in PostgreSQL
- PostgreSQL:conteggio in esecuzione delle righe per una query 'per minuto'
- Funzione finestra Postgres e raggruppa per eccezione