Toto je velmi podobné ostatním otázkám, ale nejlepší dotaz je stále složitější.
Základní dotaz rychle získat průběžnou částku:
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);
Složitější částí je doplnění chybějících měsíců :
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;
implicitní CROSS JOIN LATERAL
vyžaduje Postgres 9.3+. Začíná prvním měsícem v tabulce.
Chcete-li začít daným měsícem :
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;
Udržujte měsíce od různých let od sebe. O to jste nežádali, ale s největší pravděpodobností to budete chtít.
Všimněte si, že „měsíc“ do určité míry závisí na nastavení časového pásma aktuální relace! Podrobnosti:
Související:
- Výpočet kumulativního součtu v PostgreSQL
- PostgreSQL:průběžný počet řádků pro dotaz „po minutách“
- Funkce okna Postgres a skupina podle výjimky