On Tue, Jul 27, 2010 at 09:25:05PM -0400, Patrick May wrote: > On Jul 27, 2010, at 9:21 PM, Steve Atkins wrote: > > select date_trunc('hour', foo) + interval '30 minutes' * floor(extract(minute from foo) / 30) as start, event, count(*) from bar group by 1, 2 order by 1 asc; > > Thanks! It looks like interval is what I need to play with. Another useful tool to use is the classic unix "seconds since epoch". You could turn the key expression from above into: timestamp 'epoch' + interval '1 second' * floor(date_part('epoch',foo) / (30*60)) * (30*60) I'd probably go with Steve's version here, it's a bit more obvious what's going on. Also note, that if you don't really care about what the specific groups are, just that you have a set of evenly divided 30minute periods you don't need to convert back to a date, so could just use: floor(date_part('epoch',foo) / (30*60)) One final note, if you're dealing with lots of data and the above expression is slow, you could delay converting back to a date until "after" the grouping, i.e: SELECT timestamp 'epoch' + interval '1 second' * floor(date_part('epoch',foo) / (30*60)) * (30*60) AS t, COUNT(*) FROM data GROUP BY floor(date_part('epoch',foo) / (30*60)); This will save PG from converting back to a date for every row when it's going to chuck most of them away anyway. Hope that gives you some more ideas! -- Sam http://samason.me.uk/ -- Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-general