List the total slots booked per facility per month

Question

Produce a list of the total number of slots booked per facility per month in the year of 2012. Produce an output table consisting of facility id and slots, sorted by the id and month.

Expected Results

facidmonthTotal Slots
07270
08459
09591
17207
18483
19588
27180
28459
29570
37104
38304
39422
47264
48492
49648
5724
5882
59122
67164
68400
69540
77156
78326
79426
87117
88322
89471

Your Answer

Your Results

Loading database...

Answers and Discussion

select facid, extract(month from starttime) as month, sum(slots) as "Total Slots"
	from cd.bookings
	where extract(year from starttime) = 2012
	group by facid, month
order by facid, month;

The main piece of new functionality in this question is the EXTRACT function. EXTRACT allows you to get individual components of a timestamp, like day, month, year, etc. We group by the output of this function to provide per-month values. An alternative, if we needed to distinguish between the same month in different years, is to make use of the DATE_TRUNC function, which truncates a date to a given granularity. It's also worth noting that this is the first time we've truly made use of the ability to group by more than one column.

One thing worth considering with this answer: the use of the EXTRACT function in the WHERE clause has the potential to cause severe issues with performance on larger tables. If the timestamp column has a regular index on it, Postgres will not understand that it can use the index to speed up the query and will instead have to scan through the whole table. You've got a couple of options here:

  • Consider creating an expression-based index on the timestamp column. With appropriately specified indexes Postgres can use indexes to speed up WHERE clauses containing function calls.
  • Alter the query to be a little more verbose, but use more standard comparisons, for example:
    select facid, extract(month from starttime) as month, sum(slots) as "Total Slots"
    	from cd.bookings
    	where
    		starttime >= '2012-01-01'
    		and starttime < '2013-01-01'
    	group by facid, month
    order by facid, month;
    Postgres is able to use an index using these standard comparisons without any additional assistance.