Thread: Showing a cumlative total by month

Showing a cumlative total by month

From
David Nelson
Date:
<div dir="ltr">Good morning all,<br /><br />We have a system that maintains information about files that have been
uploadedto our system. I have a view that shows for each month the total size of all files submitted tht month. I would
liketo add a running total column to the view, but can't quite get there. I figured out how to show the information I
wantusing a CTE, but I can not figure out how to translate that to a single query to define a view with. So I'm hoping
someonecan point me in the right direction.<br /><br />SELECT VERSION();<br />                            version      
                                            <br
/>----------------------------------------------------------------------------------------------------------------<br
/> PostgreSQL9.1.18 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11), 64-bit<br
/><br/>DROP TABLE uploaded_files;<br /><br />CREATE TABLE uploaded_files<br />(<br />   file_id              SERIAL    
                  NOT NULL,<br />   upload_date          TIMESTAMP WITH TIME ZONE      NOT NULL,<br />   upload_size  
      BIGINT                        NOT NULL,<br />   PRIMARY KEY (file_id)<br />);<br /><br />This test case is
populatedwith a handful of random records (659), and the following CTE seems to extract the information I am after
(stillnot positive I have the date down exactly, but I can deal with that):<br /><br />WITH upload_summary AS<br />(<br
/>  SELECT EXTRACT(YEAR FROM upload_date) AS up_year,<br />          LPAD(CAST(EXTRACT(MONTH FROM upload_date) AS
TEXT),2, '0') AS up_month,<br />          SUM(upload_size) AS monthly_total<br />   FROM uploaded_files<br />   GROUP
BYup_month, up_year<br />)<br />SELECT u.up_year,<br />       u.up_month,<br />       u.monthly_total,<br />     
 (SELECTSUM(monthly_total)<br />        FROM upload_summary<br />        WHERE CAST(CONCAT(up_year,<br />             
           '-',<br />                          up_month,<br />                          '-01 00:00:00-05')<br />       
          AS TIMESTAMP) <=<br />              CAST(CONCAT(u.up_year,<br />                          '-',<br />     
                   u.up_month,<br />                          '-01 00:00:00-05')<br />                   AS
TIMESTAMP)<br/>       ) AS cumulative<br />FROM upload_summary u<br />ORDER BY up_year, up_month;<br /><br /> up_year |
up_month| monthly_total  |   cumulative  <br />---------+----------+----------------+----------------<br />    2014 |
01      |     3179135699 |     3179135699<br />    2014 | 02       |     1634499060 |     4813634759<br />    2014 | 03
     |     4278982588 |     9092617347<br />    2014 | 04       |   142238544857 |   151331162204<br />    2014 | 05  
   |   357240707209 |   508571869413<br />    2014 | 06       |    64339859968 |   572911729381<br />    2014 | 07    
 |    25513017728 |   598424747109<br />    2014 | 08       |    11020669492 |   609445416601<br />    2014 | 09      
|    1018774598 |   610464191199<br />    2014 | 10       |    76752535951 |   687216727150<br />    2014 | 11       |
   4611404964 |   691828132114<br />    2014 | 12       |    69607199452 |   761435331566<br />    2015 | 01       |  
   15700525 |   761451032091<br />    2015 | 02       |    34234715981 |   795685748072<br />    2015 | 03       |
 1484150449194|  2279836197266<br />    2015 | 04       | 13096208914706 | 15376045111972<br />    2015 | 05       |  
  814385166 | 15376859497138<br />    2015 | 06       |      563829413 | 15377423326551<br />    2015 | 07       |    
 656007272| 15378079333823<br />    2015 | 08       |  1828956674258 | 17207036008081<br />    2015 | 09       |    
 822601322| 17207858609403<br /><br /><br /><br />The basic view definition gives the first three columns (date fields
concatenatedinto one):<br />SELECT CONCAT(EXTRACT(YEAR FROM upload_date),<br />              '-',<br />             
LPAD(CAST(EXTRACT(MONTHFROM upload_date) AS TEXT), 2, '0')) AS mon,<br />       SUM(upload_size) AS monthly_total<br
/>FROMuploaded_files u<br />GROUP BY EXTRACT(MONTH FROM upload_date), EXTRACT(YEAR FROM upload_date)<br />ORDER BY
EXTRACT(YEARFROM upload_date), EXTRACT(MONTH FROM upload_date);<br /><br />   mon   | monthly_total<br
/>---------+----------------<br/> 2014-01 |     3179135699<br /> 2014-02 |     1634499060<br /> 2014-03 |    
4278982588<br/> 2014-04 |   142238544857<br /> 2014-05 |   357240707209<br /> 2014-06 |    64339859968<br /> 2014-07 |
  25513017728<br /> 2014-08 |    11020669492<br /> 2014-09 |     1018774598<br /> 2014-10 |    76752535951<br
/> 2014-11|     4611404964<br /> 2014-12 |    69607199452<br /> 2015-01 |       15700525<br /> 2015-02 |  
 34234715981<br/> 2015-03 |  1484150449194<br /> 2015-04 | 13096208914706<br /> 2015-05 |      814385166<br /> 2015-06
|     563829413<br /> 2015-07 |      656007272<br /> 2015-08 |  1828956674258<br /> 2015-09 |      822601322<br /><br
/><br/>I just can't figure out how to specify the summation of the file sizes through each month in a static query. Any
suggestions?<br/><br />Thanks,<br />David</div> 

Re: Showing a cumlative total by month

From
"David G. Johnston"
Date:
On Fri, Sep 11, 2015 at 10:46 AM, David Nelson <dnelson77808@gmail.com> wrote:
I would like to add a running total column to the view, but can't quite get there. I figured out how to show the information I want using a CTE, but I can not figure out how to translate that to a single query to define a view with. So I'm hoping someone can point me in the right direction.



David J.​
 

Re: Showing a cumlative total by month

From
David Nelson
Date:
<div dir="ltr">On Fri, Sep 11, 2015 at 10:15 AM, David G. Johnston <<a
href="mailto:david.g.johnston@gmail.com">david.g.johnston@gmail.com</a>>wrote:<br />><br />> On Fri, Sep 11,
2015at 10:46 AM, David Nelson <<a href="mailto:dnelson77808@gmail.com">dnelson77808@gmail.com</a>> wrote:<br
/>>><br/>>> I would like to add a running total column to the view, but can't quite get there. I figured
outhow to show the information I want using a CTE, but I can not figure out how to translate that to a single query to
definea view with. So I'm hoping someone can point me in the right direction.<br />>><br />><br />> -->
 <a
href="http://www.postgresql.org/docs/9.3/interactive/functions-window.html">http://www.postgresql.org/docs/9.3/interactive/functions-window.html</a><br
/>><br/>> David J.<br />>  <br />Ha! How ironic. I made myself a note to try to understand windowing
functions<br/>a couple of weeks ago due to a conversation on one of the PostgreSQL lists<br />regarding finding first
andlast values. Looks like that just got moved up<br />in priority.<br /><br />Thanks!<br /><br />I'll post that
solutionwhen I find it for posterity.<br /></div> 

Re: Showing a cumlative total by month

From
David Nelson
Date:
On Fri, Sep 11, 2015 at 10:01 AM, Stuart <sfbarbee@gmail.com> wrote:

David,

You can't just use the query you have to define a new view?  Seems straight forward.  Am I missing something?

Stuart

CCing the list.

Stuart, it turns out you are right. I assumed that the CTE solution wouldn't
work because a view definition needs to be a "simple" SELECT. But I didn't
test that and a quick test reveals it seems to work. I'll have to play around
with David Johnston's pointer to the windowing function as well to see which
is more likely to be future proof for production. But shame on me for not
trying it first and thanks for the prod.

David
 
On Sep 11, 2015 18:46, "David Nelson" <dnelson77808@gmail.com> wrote:
Good morning all,

We have a system that maintains information about files that have been uploaded to our system. I have a view that shows for each month the total size of all files submitted tht month. I would like to add a running total column to the view, but can't quite get there. I figured out how to show the information I want using a CTE, but I can not figure out how to translate that to a single query to define a view with. So I'm hoping someone can point me in the right direction.

SELECT VERSION();
                            version                                                    
----------------------------------------------------------------------------------------------------------------
 PostgreSQL 9.1.18 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11), 64-bit

DROP TABLE uploaded_files;

CREATE TABLE uploaded_files
(
   file_id              SERIAL                        NOT NULL,
   upload_date          TIMESTAMP WITH TIME ZONE      NOT NULL,
   upload_size          BIGINT                        NOT NULL,
   PRIMARY KEY (file_id)
);

This test case is populated with a handful of random records (659), and the following CTE seems to extract the information I am after (still not positive I have the date down exactly, but I can deal with that):

WITH upload_summary AS
(
   SELECT EXTRACT(YEAR FROM upload_date) AS up_year,
          LPAD(CAST(EXTRACT(MONTH FROM upload_date) AS TEXT), 2, '0') AS up_month,
          SUM(upload_size) AS monthly_total
   FROM uploaded_files
   GROUP BY up_month, up_year
)
SELECT u.up_year,
       u.up_month,
       u.monthly_total,
       (SELECT SUM(monthly_total)
        FROM upload_summary
        WHERE CAST(CONCAT(up_year,
                          '-',
                          up_month,
                          '-01 00:00:00-05')
                   AS TIMESTAMP) <=
              CAST(CONCAT(u.up_year,
                          '-',
                          u.up_month,
                          '-01 00:00:00-05')
                   AS TIMESTAMP)
       ) AS cumulative
FROM upload_summary u
ORDER BY up_year, up_month;

 up_year | up_month | monthly_total  |   cumulative  
---------+----------+----------------+----------------
    2014 | 01       |     3179135699 |     3179135699
    2014 | 02       |     1634499060 |     4813634759
    2014 | 03       |     4278982588 |     9092617347
    2014 | 04       |   142238544857 |   151331162204
    2014 | 05       |   357240707209 |   508571869413
    2014 | 06       |    64339859968 |   572911729381
    2014 | 07       |    25513017728 |   598424747109
    2014 | 08       |    11020669492 |   609445416601
    2014 | 09       |     1018774598 |   610464191199
    2014 | 10       |    76752535951 |   687216727150
    2014 | 11       |     4611404964 |   691828132114
    2014 | 12       |    69607199452 |   761435331566
    2015 | 01       |       15700525 |   761451032091
    2015 | 02       |    34234715981 |   795685748072
    2015 | 03       |  1484150449194 |  2279836197266
    2015 | 04       | 13096208914706 | 15376045111972
    2015 | 05       |      814385166 | 15376859497138
    2015 | 06       |      563829413 | 15377423326551
    2015 | 07       |      656007272 | 15378079333823
    2015 | 08       |  1828956674258 | 17207036008081
    2015 | 09       |      822601322 | 17207858609403



The basic view definition gives the first three columns (date fields concatenated into one):
SELECT CONCAT(EXTRACT(YEAR FROM upload_date),
              '-',
              LPAD(CAST(EXTRACT(MONTH FROM upload_date) AS TEXT), 2, '0')) AS mon,
       SUM(upload_size) AS monthly_total
FROM uploaded_files u
GROUP BY EXTRACT(MONTH FROM upload_date), EXTRACT(YEAR FROM upload_date)
ORDER BY EXTRACT(YEAR FROM upload_date), EXTRACT(MONTH FROM upload_date);

   mon   | monthly_total
---------+----------------
 2014-01 |     3179135699
 2014-02 |     1634499060
 2014-03 |     4278982588
 2014-04 |   142238544857
 2014-05 |   357240707209
 2014-06 |    64339859968
 2014-07 |    25513017728
 2014-08 |    11020669492
 2014-09 |     1018774598
 2014-10 |    76752535951
 2014-11 |     4611404964
 2014-12 |    69607199452
 2015-01 |       15700525
 2015-02 |    34234715981
 2015-03 |  1484150449194
 2015-04 | 13096208914706
 2015-05 |      814385166
 2015-06 |      563829413
 2015-07 |      656007272
 2015-08 |  1828956674258
 2015-09 |      822601322


I just can't figure out how to specify the summation of the file sizes through each month in a static query. Any suggestions?

Thanks,
David

Re: Showing a cumlative total by month

From
David Nelson
Date:
<div dir="ltr">On Fri, Sep 11, 2015 at 10:15 AM, David G. Johnston <<a
href="mailto:david.g.johnston@gmail.com">david.g.johnston@gmail.com</a>>wrote:<br />><br />> On Fri, Sep 11,
2015at 10:46 AM, David Nelson <<a href="mailto:dnelson77808@gmail.com">dnelson77808@gmail.com</a>> wrote:<br
/>>><br/>>> I would like to add a running total column to the view, but can't quite get there. I figured
outhow to show the information I want using a CTE, but I can not figure out how to translate that to a single query to
definea view with. So I'm hoping someone can point me in the right direction.<br />>><br />><br />> -->
 <a
href="http://www.postgresql.org/docs/9.3/interactive/functions-window.html">http://www.postgresql.org/docs/9.3/interactive/functions-window.html</a><br
/>><br/>> David J.<br />>  <br /><br />Thanks David and Stuart!<br /><br />these two solutions seem to be what
I'mafter. I will apply them to the<br />production view (which is more complex), and see how they play out. But you<br
/>twopointed me in the directions that I needed to go.<br /><br />DROP VIEW upload_info;<br /><br />CREATE VIEW
upload_infoAS<br />SELECT mon,<br />       monthly_total,<br />       SUM(monthly_total) OVER (ORDER BY mon) AS
cumulative<br/>FROM (SELECT CONCAT(EXTRACT(YEAR FROM upload_date),<br />                    '-',<br
/>                   LPAD(CAST(EXTRACT(MONTH FROM upload_date) AS TEXT), 2, '0')) AS mon,<br />            
SUM(upload_size)AS monthly_total<br />      FROM uploaded_files u<br />      GROUP BY EXTRACT(MONTH FROM upload_date),
EXTRACT(YEARFROM upload_date)<br />      ORDER BY EXTRACT(YEAR FROM upload_date), EXTRACT(MONTH FROM upload_date)) AS
u;<br/><br />SELECT *<br />FROM upload_info;<br /><br />   mon   | monthly_total  |   cumulative   <br
/>---------+----------------+----------------<br/> 2014-01 |     3179135699 |     3179135699<br /> 2014-02 |    
1634499060|     4813634759<br /> 2014-03 |     4278982588 |     9092617347<br /> 2014-04 |   142238544857 |  
151331162204<br/> 2014-05 |   357240707209 |   508571869413<br /> 2014-06 |    64339859968 |   572911729381<br
/> 2014-07|    25513017728 |   598424747109<br /> 2014-08 |    11020669492 |   609445416601<br /> 2014-09 |    
1018774598|   610464191199<br /> 2014-10 |    76752535951 |   687216727150<br /> 2014-11 |     4611404964 |  
691828132114<br/> 2014-12 |    69607199452 |   761435331566<br /> 2015-01 |       15700525 |   761451032091<br
/> 2015-02|    34234715981 |   795685748072<br /> 2015-03 |  1484150449194 |  2279836197266<br /> 2015-04 |
13096208914706| 15376045111972<br /> 2015-05 |      814385166 | 15376859497138<br /> 2015-06 |      563829413 |
15377423326551<br/> 2015-07 |      656007272 | 15378079333823<br /> 2015-08 |  1828956674258 | 17207036008081<br
/> 2015-09|      822601322 | 17207858609403<br />(21 rows)<br /><br /><br /><br />DROP VIEW upload_info;<br /><br
/>CREATEVIEW upload_info AS<br />WITH upload_summary AS<br />(<br />   SELECT EXTRACT(YEAR FROM upload_date) AS
up_year,<br/>          LPAD(CAST(EXTRACT(MONTH FROM upload_date) AS TEXT), 2, '0') AS up_month,<br />         
SUM(upload_size)AS monthly_total<br />   FROM uploaded_files<br />   GROUP BY up_month, up_year<br />)<br />SELECT
u.up_year,<br/>       u.up_month,<br />       u.monthly_total,<br />       (SELECT SUM(monthly_total)<br />        FROM
upload_summary<br/>        WHERE CAST(CONCAT(up_year,<br />                          '-',<br
/>                         up_month,<br />                          '-01 00:00:00-05')<br />                   AS
TIMESTAMP)<=<br />              CAST(CONCAT(u.up_year,<br />                          '-',<br
/>                         u.up_month,<br />                          '-01 00:00:00-05')<br />                   AS
TIMESTAMP)<br/>       ) AS cumulative<br />FROM upload_summary u<br />ORDER BY up_year, up_month;<br /><br />SELECT
*<br/>FROM upload_info;<br /><br /> up_year | up_month | monthly_total  |   cumulative   <br
/>---------+----------+----------------+----------------<br/>    2014 | 01       |     3179135699 |     3179135699<br
/>   2014 | 02       |     1634499060 |     4813634759<br />    2014 | 03       |     4278982588 |     9092617347<br
/>   2014 | 04       |   142238544857 |   151331162204<br />    2014 | 05       |   357240707209 |   508571869413<br
/>   2014 | 06       |    64339859968 |   572911729381<br />    2014 | 07       |    25513017728 |   598424747109<br
/>   2014 | 08       |    11020669492 |   609445416601<br />    2014 | 09       |     1018774598 |   610464191199<br
/>   2014 | 10       |    76752535951 |   687216727150<br />    2014 | 11       |     4611404964 |   691828132114<br
/>   2014 | 12       |    69607199452 |   761435331566<br />    2015 | 01       |       15700525 |   761451032091<br
/>   2015 | 02       |    34234715981 |   795685748072<br />    2015 | 03       |  1484150449194 |  2279836197266<br
/>   2015 | 04       | 13096208914706 | 15376045111972<br />    2015 | 05       |      814385166 | 15376859497138<br
/>   2015 | 06       |      563829413 | 15377423326551<br />    2015 | 07       |      656007272 | 15378079333823<br
/>   2015 | 08       |  1828956674258 | 17207036008081<br />    2015 | 09       |      822601322 | 17207858609403<br
/>(21rows)<br /></div>