I have tried several solutions but the only one close enough to what i want is this
Sale.all.group("DATE_TRUNC('month', created_at)").count
but it returns something like this
{2016-07-01 00:00:00 UTC=>19, 2016-04-01 00:00:00 UTC=>70}
is there something that can do this format?
[month,number of sales] ??
using postgres db.
try use EXTRACT function of postgresql,
in Rails code
results = Sale.all.group("EXTRACT(MONTH FROM created_at").select("EXTRACT(MONTH FROM created_at) AS month, COUNT(*) as count")
p results[0].month if results[0]
Related
I want to get only those records of my model which belong to a particular month. I am using:
Order.where(created_at.strftime("%B"): "April")
where created_at is DateTime. created_at.strftime("%B") gives me month, but it does not work. Any alternative?
You'll probably have to do this in plan SQL (not the activerecord DSL):
Order.where("strftime('%m', created_at) = ?", 'April')
This uses the SQLite function to extract the month name
(I haven't done Rails in a while, let me know if this doesn't work)
I have a document that has been generated, say, on 2017-10-03 15:02:47.
Then I have this Rails/SQL query (it doesn't matter if I run it through Rails or straight through the SQL console, the results are the same):
SELECT * FROM table where needed_column <= '2017-10-03';
This query would not return me the document that has been generated on 2017-10-03 15:02:47. If I do run, though, this query:
SELECT * FROM table where needed_column <= '2017-10-03 23:59:59';
Then I get the needed document (generated on 2017-10-03 15:02:47).
To solve this issue, I can manually add the time to the query (23:59:59), but it's not a very elegant solution.
I am using Rails 5, AR, PostgreSQL - is there a better way to solve this problem than to manually add the time stamp to the query?
Thank you
Your needed_column is probably saving timestamps (Date and Time). As you already figured it out you need to compare it with another timestamp or cast needed_column using ::date
Model.where("needed_column::date <= '2017-10-03'")
This will generate:
SELECT table.* FROM table WHERE (needed_column::date <= '2017-10-03')
Try this in Rails:-
Model.where(needed_column: [Time.now.at_beginning_of_day, Time.now.end_of_day])
Or as sql query:-
SELECT * FROM table_name WHERE needed_column BETWEEN '2017-10-09 00:00:00 UTC' AND '2017-10-09 23:59:59 UTC'
I'm trying to figure out how to do a query where created_at.year == a given year, and created_at.month equals a given month.
However I can't figure out what I'm doing wrong.
Model.where("'created_at.month' = ? AND 'created_at.year' = ?", 7,2013)
results in nothing being shown.
However when I try Model.first.created_at.month ==7 and
Model.first.created_at.year ==2013 I get true for both.
Therefore theoretically my query should be at least be returning my first record.
Anyone know what I'm doing wrong or any alternative way to find records created on specific months?
Note that in my views the month / year will be parameters but for the purposes of this example I used actual values.
using ruby 1.9.3
rails 3.2.13
You can use the extract SQL function, that will extract the month and year of the timestamp:
Model.where('extract(year from created_at) = ? and extract(month from created_at) = ?', '2013','7')
This query should give you the desired result.
created_at is a timestamp; it is not a set of discrete fields in the database. created_at.year and such don't exist in your DB; it's simply a single timestamp field. When you call #model.created_at.year, Rails is loading the created_at field from the database, and creating a Time object from it, which has a #year method you can call.
What you want is to query on a range of dates:
Model.where("created_at >= ? and created_at < ?", Time.mktime(2013, 7), Time.mktime(2013, 8))
This will find any Model with a created_at timestamp in July 2013.
I have in my db a attribute where i save the record creation date.
The saved date has this format:
2013/06/18 19:03:24
I need to search only for date and i am not interested the time
I have try in this mode but it's doesn't work:
Report.find_all_by_created_at("2013-06-18").each do |r| %>
[...]
end
Given that created_at is a Rails generated column you can't really and just for created at date. Reason for that is in database created_at is saved as timestamp (or Datetime) so records created on 18th of June may have values from 2013-06-18 00:00:00 to 2013-06-18 23:59:59.
So, if you'd like to select all objects created on specific day you should do something like
Report.where('created_at >= ? AND created_at <= ?, Date.new(2013,6,18).beginning_of_day, Date.new(2013,6,18).end_of_day)
You can pass a range to where:
date = Date.new(2013,6,18)
Report.where(created_at: date.beginning_of_day..date.end_of_day)
This creates a SQL statement like:
SELECT `reports`.* FROM `reports` WHERE `reports`.`created_at` BETWEEN '2013-06-18 00:00:00' AND '2013-06-18 23:59:59'
Probably not the best solution but you could do:
Report.where("created_at >= ? and created_at < ?","2013-06-18","2013,06-19").each do |r|
[...]
end
It looks like you are collecting it as a DateTime and you would probably be able to use the to_date() method to change it to a Date object which would be searchable.
http://api.rubyonrails.org/classes/DateTime.html#method-i-to_date
you can use like matcher in sql query
Report.where("created_at LIKE '2013-06-18%'")
or look at the Squeel gem it can call SQL functions in ruby like syntax then you could use something thati will generate query with
WHERE cast(created_at as date) = '2013-06-18'
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)
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)
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.
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.