Instead of comparing with the extracted value you need to use a range table. Something like this:
month startOfMonth nextMonth 1 '2014-01-01' '2014-02-01' 2 '2014-02-01' '2014-03-01' ...... 12 '2014-12-01' '2015-01-01'
As in @Roman's answer, we start with generate_series() , this time using it to create a range table:
WITH Month_Range AS (SELECT EXTRACT(MONTH FROM month) AS month, month AS startOfMonth, month + INTERVAL '1 MONTH' AS nextMonth FROM generate_series(CAST('2014-01-01' AS DATE), CAST('2014-12-01' AS DATE), INTERVAL '1 month') AS mr(month)) SELECT Month_Range.month, COUNT(My_Table) FROM Month_Range LEFT JOIN My_Table ON My_Table.time >= Month_Range.startOfMonth AND My_Table.time < Month_Range.nextMonth AND my_table.id_object = 1 AND my_table.status = 1 GROUP BY Month_Range.month ORDER BY Month_Range.month
(As a side note, I'm now annoyed at how PostgreSQL handles intervals)
SQL Fiddle Demo
Using a range will allow you to use any index, including My_Table.time (although not if the index was built on an EXTRACT ed column.
EDIT:
A modified request to take advantage of the fact that generate_series(...) will also handle dates / time series.
Clockwork-Muse Jun 11 '14 at 11:38 on 2014-06-11 11:38
source share