Обсуждение: monthly tally of new memberships

Поиск
Список
Период
Сортировка

monthly tally of new memberships

От
brian
Дата:
I'm trying to create a select statement that will show me the number of
new memberships or an organisation by date (first of each month). The
member table has a date column to reflect when the member was inserted.
So far, i've gotten as far as:

SELECT applied AS date_applied, count(id) AS applications
FROM member WHERE applied = applied
GROUP BY applied
ORDER BY date_applied ASC;

date_applied  |    applications

  2006-05-21   |            1
  2006-05-22   |            1
  2006-05-23   |            2
  2006-05-24   |           14
  2006-05-25   |            5

etc.

This returns the new memberships for each day, ignoring days without
any. What i'd like to do though, is to select only the 1st of each
month, summing the new memberships or that month, eg:

     month     |     applications
  2006-05-01   |           57
  2006-06-01   |           36
  2006-07-01   |           72

etc.

I've been fiddling with this since yesterday and am getting no closer,
it seems. I know how to do this if i pass in a particular month to
select from but not an aggregate for the entire month. Nothing i've
tried is working but this seems as if it should be quite simple.

I'll bet it's obvious, isn't it? :-\

brian

Re: monthly tally of new memberships

От
Michael Glaesemann
Дата:
On Jul 18, 2007, at 13:29 , brian wrote:

> This returns the new memberships for each day, ignoring days
> without any. What i'd like to do though, is to select only the 1st
> of each month, summing the new memberships or that month, eg:
>
>     month     |     applications
>  2006-05-01   |           57
>  2006-06-01   |           36
>  2006-07-01   |           72

Try something like this:

SELECT date_trunc('month', applied)::date AS date_applied
     , count(id) AS applications
FROM member
GROUP BY applied
ORDER BY date_applied ASC;

Note I remove the WHERE applied = applied, as this is just identity.

Michael Glaesemann
grzm seespotcode net



Re: monthly tally of new memberships

От
Jon Sime
Дата:
brian wrote:
> I'm trying to create a select statement that will show me the number of
> new memberships or an organisation by date (first of each month). The
> member table has a date column to reflect when the member was inserted.
> So far, i've gotten as far as:
>
> SELECT applied AS date_applied, count(id) AS applications
> FROM member WHERE applied = applied
> GROUP BY applied
> ORDER BY date_applied ASC;

Try this instead:

     select to_char(applied, 'yyyy-mm') as month_applied,
         count(id) as applications
     from member
     group by to_char(applied, 'yyyy-mm')
     order by 1 asc;

Your WHERE condition seems superfluous, unless you're using that to
remove any records where applied is NULL. If that's the case, it would
be much more readable and intuitive to use "where applied is not null".

-Jon

--
Senior Systems Developer
Media Matters for America
http://mediamatters.org/

Re: monthly tally of new memberships

От
brian
Дата:
Michael Glaesemann wrote:
>
> On Jul 18, 2007, at 13:29 , brian wrote:
>
>> This returns the new memberships for each day, ignoring days
>> without any. What i'd like to do though, is to select only the 1st
>> of each month, summing the new memberships or that month, eg:
>>
>> month     |     applications 2006-05-01   |           57 2006-06-01
>> |           36 2006-07-01   |           72
>
>
> Try something like this:
>
> SELECT date_trunc('month', applied)::date AS date_applied , count(id)
> AS applications FROM member GROUP BY applied ORDER BY date_applied
> ASC;
>
> Note I remove the WHERE applied = applied, as this is just identity.
>

Thanks, but that isn't it. I've tried that exact query, actually. The
problem with that is it doesn't give me one row for the entire month.
Instead, i get one row for each day there was a new membership, only the
date_applied column has been changed to the 1st of that particular
month. eg:

  2006-02-01   |            1
  2006-02-01   |            1
  2006-02-01   |            7
  2006-03-01   |            1
  2006-03-01   |            3
  2006-03-01   |            1
  2006-03-01   |            3
  2006-03-01   |            1
  2006-03-01   |            2

What i'd like to be able to do is to count all of the new member IDs
that have been inserted during a particular month and return that sum
along with the date for the 1st (ie '2006-03-22').

The thing is, i feel certain that i've done something very similar before.

brian

Re: monthly tally of new memberships

От
Alvaro Herrera
Дата:
brian wrote:
> Michael Glaesemann wrote:
>> On Jul 18, 2007, at 13:29 , brian wrote:
>>> This returns the new memberships for each day, ignoring days
>>> without any. What i'd like to do though, is to select only the 1st
>>> of each month, summing the new memberships or that month, eg:
>>> month     |     applications 2006-05-01   |           57 2006-06-01
>>> |           36 2006-07-01   |           72
>> Try something like this:
>> SELECT date_trunc('month', applied)::date AS date_applied , count(id)
>> AS applications FROM member GROUP BY applied ORDER BY date_applied
>> ASC;
>> Note I remove the WHERE applied = applied, as this is just identity.
>
> Thanks, but that isn't it. I've tried that exact query, actually. The
> problem with that is it doesn't give me one row for the entire month.
> Instead, i get one row for each day there was a new membership, only the
> date_applied column has been changed to the 1st of that particular month.
> eg:

Hum, you should be grouping by date_applied (also known as "group by 1"
because you can't use column aliases in GROUP BY)

--
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

Re: monthly tally of new memberships

От
brian
Дата:
Alvaro Herrera wrote:
> brian wrote:
>
>>Michael Glaesemann wrote:
>>
>>>On Jul 18, 2007, at 13:29 , brian wrote:
>>>
>>>>This returns the new memberships for each day, ignoring days
>>>>without any. What i'd like to do though, is to select only the 1st
>>>>of each month, summing the new memberships or that month, eg:
>>>>month     |     applications 2006-05-01   |           57 2006-06-01
>>>>|           36 2006-07-01   |           72
>>>
>>>Try something like this:
>>>SELECT date_trunc('month', applied)::date AS date_applied , count(id)
>>>AS applications FROM member GROUP BY applied ORDER BY date_applied
>>>ASC;
>>>Note I remove the WHERE applied = applied, as this is just identity.
>>
>>Thanks, but that isn't it. I've tried that exact query, actually. The
>>problem with that is it doesn't give me one row for the entire month.
>>Instead, i get one row for each day there was a new membership, only the
>>date_applied column has been changed to the 1st of that particular month.
>>eg:
>
>
> Hum, you should be grouping by date_applied (also known as "group by 1"
> because you can't use column aliases in GROUP BY)
>

Right, that works, also.

I compared this to Jon Sime's suggestion:

test=# EXPLAIN ANALYZE  SELECT date_trunc('month', applied)::date AS
date_applied, count(id) AS applications FROM member GROUP BY 1 ORDER BY
date_applied ASC;

QUERY PLAN
-------------------------------------------------------
Sort  (cost=140.76..141.26 rows=200 width=8) (actual time=17.590..17.622
rows=18 loops=1)
Sort Key: (date_trunc('month'::text, (applied)::timestamp with time
zone))::date
    ->  HashAggregate  (cost=129.12..133.12 rows=200 width=8) (actual
time=17.478..17.523 rows=18 loops=1)
          ->  Seq Scan on member  (cost=0.00..123.76 rows=1072 width=8)
(actual time=0.035..10.684 rows=1072 loops=1)
  Total runtime: 17.733 ms
(5 rows)

test=# EXPLAIN ANALYZE SELECT to_char(applied, 'yyyy-mm') AS
month_applied, count(id) AS applications FROM member GROUP BY
to_char(applied, 'yyyy-mm') ORDER BY 1 ASC;

QUERY PLAN
-----------------------------------------------------
  Sort  (cost=137.58..138.08 rows=200 width=8) (actual
time=13.415..13.458 rows=18 loops=1)
    Sort Key: to_char((applied)::timestamp with time zone, 'yyyy-mm'::text)
    ->  HashAggregate  (cost=126.44..129.94 rows=200 width=8) (actual
time=13.273..13.314 rows=18 loops=1)
          ->  Seq Scan on member  (cost=0.00..121.08 rows=1072 width=8)
(actual time=0.042..10.525 rows=1072 loops=1)
  Total runtime: 13.564 ms
(5 rows)


But, getting back to your comment, i see that this (grouping by the
alias) also works:

test=# EXPLAIN ANALYZE SELECT to_char(applied, 'yyyy-mm') AS
month_applied, count(id) AS applications FROM member GROUP BY
month_applied ORDER BY 1 ASC;

QUERY PLAN
-----------------------------------------------------
  Sort  (cost=137.58..138.08 rows=200 width=8) (actual
time=44.329..44.363 rows=18 loops=1)
    Sort Key: to_char((applied)::timestamp with time zone, 'yyyy-mm'::text)
    ->  HashAggregate  (cost=126.44..129.94 rows=200 width=8) (actual
time=44.190..44.229 rows=18 loops=1)
          ->  Seq Scan on member  (cost=0.00..121.08 rows=1072 width=8)
(actual time=0.042..41.242 rows=1072 loops=1)
  Total runtime: 44.477 ms
(5 rows)


But it seems to take longer at the cost of keeping the query tidy.

brian