9

How do I group by hour in Postgres & Rails? I've read through quite a few SO answers but I'm getting errors.

This works when grouping by date:

Model.group("date(updated_at)").count

Then I tried the following for hour but they didn't work:

Model.group("hour(updated_at)").count
Model.group("date_format(updated_at, '%H')").count
Model.group("extract(hour from updated_at)").count

Once I've found certain hours I need to update, how would I then get the models with those hours? I.e:

Model.where("hour(updated_at) = ?", 5)
Alex Kojin
  • 5,044
  • 2
  • 29
  • 31
mind.blank
  • 4,820
  • 3
  • 22
  • 49

3 Answers3

16

You could try the following

Model.group("DATE_PART('hour', updated_at)").count

UPDATE:

How to find records

Model.where("DATE_PART('hour', updated_at) = ?", 5)
schmijos
  • 8,114
  • 3
  • 50
  • 58
jvnill
  • 29,479
  • 4
  • 83
  • 86
1

PostgreSQL presents two ways to extract a part of date/time:

EXTRACT is SQL standard function that exists in other SQL based databases.

Model.group("EXTRACT(hour FROM created_at)").count
Model.where("EXTRACT(hour FROM created_at) = ?", 5)

date_part function

Model.group("date_part('hour', updated_at)").count
Model.where("date_part('hour', updated_at) = ?", 5)

The official documentation.

Alex Kojin
  • 5,044
  • 2
  • 29
  • 31
0

If you want both the date and the hour, you can use date_trunc:

Model.group("date_trunc('hour', created_at)").count

And if you want the answers in order:

Model.order("date_trunc('hour', created_at)").group("date_trunc('hour', created_at)").count

Yeah it's weird that you can't just do order(:created_at) but oh well.

Will Warner
  • 1,341
  • 1
  • 8
  • 3