sql >> Database teknologi >  >> RDS >> PostgreSQL

Akkumuleret sum af værdier pr. måned, udfyldt for manglende måneder

Dette minder meget om andre spørgsmål, men den bedste forespørgsel er stadig vanskelig.

Grundlæggende forespørgsel for at få den løbende sum hurtigt:

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);

Den vanskelige del er at udfylde for manglende måneder :

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;

implicit CROSS JOIN LATERAL kræver Postgres 9.3+. Dette starter med den første måned i tabellen.
For at starte med en given måned :

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;

SQL Fiddle.

Hold måneder fra forskellige år fra hinanden. Du bad ikke om det, men du vil højst sandsynligt have det.

Bemærk, at "måneden" til en vis grad afhænger af tidszoneindstillingen for den aktuelle session! Detaljer:

Relateret:




  1. Sådan bruges "Like" i SQL

  2. Gem streng med specialtegn som anførselstegn eller omvendt skråstreg i postgresql-tabellen

  3. Hvordan uploader man et billede til en database ved hjælp af php-script?

  4. Gemmer tekstfilindhold i DB:Forkert strengværdi:'\xEF\xBB\xBF# W...' for kolonne 'indhold' i række 1