sql >> Databáze >  >> RDS >> PostgreSQL

Kumulativní součet hodnot po měsících, doplnění chybějících měsíců

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;

SQL Fiddle.

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í:




  1. Použití libpqxx pro hromadné ukládání dat NEBO jak použít příkaz COPY v libpqxx

  2. MySQL now() změnit časové pásmo

  3. Nápověda MySQL:Optimalizujte aktualizační dotaz, který nastavuje pořadí podle pořadí jiného sloupce

  4. Vyberte, kde JSON Array obsahuje