I'm trying to get the last 5 days that an object has. Currently my code is like this
Post.uniq('performed_at').ascending.last(5).group_by{|p| p.performed_at}
but I've been getting 4 dates instead of 5 and I think it's because there are 2 entries of the last 5 that are created on the same day. How do I accurately get the last 5 days where a Post has an entry?
You could do:
Post.select('DISTINCT created_at').order('created_at DESC').limit(5).pluck(:created_at)
Assuming you just want the dates themselves, and not the unique datetimes, this would be better:
Post.order('created_at desc').uniq.limit(5).pluck('DATE(created_at)')
This will return just the unique calendar dates, without any specific times.
Just an update for this. I got it working and this is how I did it.
Post.select('performed_at').uniq.order('performed_at DESC').limit(5).pluck(:performed_at).reverse
I also added reverse since I want the array of days returned to me in chronological order. I also had it uniq() since select('DISTINCT performed_at') was still returning duplicate dates.
Hope this helps.
Related
I am using postgresql. I have one table the Shipments table and I have two date columns on the table called arrival_date and release_date, what I wanted to do is to get all the record and sort it according to the lowest days difference of arrival_date and release_date, for example:
Arrival Date, Released Date
2017-06-04, 2017-06-30
2017-05-02, 2017-05-05
So in this example the days difference of first record is 26 days and the second one is 3 days, so the second record should be the first one.
The easiest way would be to subtract the two dates using Postgres:
ordered_shipments = Shipment.order("(arrival_date - released_date) ASC")
This will subtract the Unix timestamps of the two dates and sort the difference in ascending order.
I got inspiration from this answer.
I think that you need improve your query in postgres
in example
Table
id | dateA | dateB
select dateA, dateB, age(timestamp dateA, timestamp dateB) diffdate from Table order by diffdate desc;
You may want to use sort_by! method:
Shipment.all.sort_by!{ |shipment| shipment.released_date - shipment.arrival_date }
I have a product model and orders associated to the product. I wanted to analyze all orders from creation of product to current time. I was thinking to optimize, I would take products created at day, and current time as start and end points. The next step would be to automatically pull 10 equally spaced times between start and current time and place them in an array. For each one of these dates, query orders for the 10 dates provided.
Question is, is this the best approach to analyzing order data / performance on the query? If so, how do you pull the 10 dates in between the created at and current time range in Rails.
I have the following pseudocode --
Products.where(event_id: event)[Products.where(event_id: event).first.created_at.to_i..Time.now.to_i)].each_slide(10) do |p|
# Loop through orders of the 10 pulled days
Orders.where(product_id: p.id).each do |o|
# Add products to one of the 10 pulled days
end
end
Example Pseudocode:
1st Getting the last Product's created_at value
require 'date'
prod_date = Products.where(event_id: event).last.created_at
prod_date = prod_date.to_time.strftime("%Y-%m-%d %H:%M:%S")
2nd Getting last 10 records in products table based on prod_date & date_today.
date_today = DateTime.now.strftime("%Y-%m-%d %H:%M:%S")
Products.where('event_id ? AND (created_at BETWEEN ? AND ?)', event, prod_date, date_today).limit(10)
You can also arrange it if you want by adding e.g. .order("created_at DESC")
3rd Start to iterate with you orders data from the result above.
Orders.where(product_id: p.id).each do |o|
# Add products to one of the 10 pulled days
end
====================================
I understand want you plan to do. Honestly I haven't tried that.
But, my idea for that is, for ex. you have 10 data & you want to get 3 equally spaced values.
Why not try to iterate it by 3 (but get the first value).
Imagine this is your data: 1 2 3 4 5 6 7 8 9 10
get the first = 1
iterate the next by (3) = 4, 7, 10
Result = 1, 4, 7, 10
You may need to get the first & last data, depends on how many
3 equally spaced values
you want to get from total result count.
In my app users can post content and i want users to see content from the last 3 days. Is there a wherekey that I can have that only looks for posts from the last 3 days? I am using parse as my backend.
You can use whereKey:greaterThan to solve this.
let threeDaysAgo = NSDate().dateByAddingTimeInterval(-259200)
query.whereKey("createdAt", greaterThan: threeDaysAgo)
I want to create an array of the number of items created each hour, each day.
I'm tracking how people are feeling, so my model is called TrackMood It just has a column called mood and the timestamps.
If I do
TrackMood.where(mood: "good").group("hour(created_at)").count
I get something like
{11=>4, 12=>2, 13=>2, 15=>1}
I've got 2 issues here
1 How do I add the day into this so it doesn't just add the items created yesterday at 11 o'clock to the items added today at 11 o'clock?
2 How do I make sure it says 0 for hours when nothing is created?
1) Instead of grouping on just the hours part of the date you'll need to group part of the date that is relevant i.e. the date up to the hours and not including anything more specific than that. E.g.
TrackMood.where(mood: "good").group("date_format(created_at, '%Y%m%d %H')").count
2) You're always going to get a hash back from this call even if it doesn't find any groups. If you want to check how many groups there are you can call .size or .count on it.
For PostgreSQL you can use date_part
SO-post - Rails & Postgresql: how to group queries by hour?
I need to grab the records for same day of the week for the preceeding X days of the week. There must be a better way to do it than this:
Transaction.find_by_sql "select * from transactions where EXTRACT(DOW from date) = 1 and organisation_id = 4 order by date desc limit 7"
It gets me what I need but is Postgres specific and not very "Rails-y". Date is a timestamp.
Anyone got suggestions?
How many days do you want to go back?
I have written a gem called by_star that has a dynamic finder suited for finding up to a certain number of days in the past. If the number of days was always a number you could use this finder:
Transaction.as_of_3_days_ago
If it was dynamic then I would recommend using something such as future or between, depending on if you have transactions in the future (i.e. time travel):
Transaction.future(params[:start_date].to_time)
Transaction.between(params[:start_date].to_time, Time.now)
AFAIK Rails has no any methods to do this by other way. So best, and faster, solution - build DOW index on date column and use your query.