Having a very simple table:
CREATE TABLE users ( name VARCHAR(50) NOT NULL, registered TIMESTAMP NOT NULL, CONSTRAINT users_pk PRIMARY KEY (name) );
How to select the number of user registrations in each month e.g.
Jan 2010 - 19, Feb 2010 - 0, Mar 2010 - 7
Advertisement
Answer
To get those zero entries you need to join across generate_series
:
select to_char(gen_month, 'Mon YYYY'), count(name) FROM generate_series(DATE '2010-01-01', DATE '2010-04-01', INTERVAL '1' MONTH) m(gen_month) LEFT OUTER JOIN users ON (registered BETWEEN gen_month AND gen_month + INTERVAL '1' MONTH - INTERVAL '1' DAY) GROUP BY gen_month;
You can make it a bit prettier by using date_trunc
, but then you can’t use a regular b-tree index on registered
:
select to_char(gen_month, 'Mon YYYY'), count(name) FROM generate_series(DATE '2010-01-01', DATE '2010-04-01', INTERVAL '1' MONTH) m(gen_month) LEFT OUTER JOIN users ON ( date_trunc('month', registered) = date_trunc('month', gen_month) ) GROUP BY gen_month;
If you want to pretty-print your output exactly as you wrote it, you could replace the SELECT
clause with:
SELECT format('%s - %s', to_char(gen_month, 'Mon YYYY'), count(name))