Това е много подобно на други въпроси, но най-добрата заявка все още е трудна.
Основна заявка за да получите текущата сума бързо:
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);
Сложната част е да попълните липсващи месеци :
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;
имплицитно CROSS JOIN LATERAL
изисква Postgres 9.3+. Това започва с първия месец в таблицата.
За да започнете с даден месец :
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;
Разграничаване на месеци от различни години. Не сте поискали това, но най-вероятно ще го искате.
Обърнете внимание, че „месецът“ до известна степен зависи от настройката на часовата зона на текущата сесия! Подробности:
Свързани:
- Изчисляване на кумулативна сума в PostgreSQL
- PostgreSQL:текущо преброяване на редове за заявка "по минути"
- Прозоречна функция на Postgres и групиране по изключение