问题
Given a table like so:
Log:
id, user_id, points, created_at
With Rails, how can I query the database by user_id and then GROUPED by week via created_at where I can then having something like:
WEEK of X/XX/XXXX - 3011 total points
WEEK of X/XX/XXXX - 320 total points
WEEK of X/XX/XXXX - 31 total points
WEEK of X/XX/XXXX - 30330 total points
Thanks
回答1:
points_by_week = Log.where(user_id: user_id).group("DATE_TRUNC('year', created_at)", "DATE_TRUNC('week', created_at)").sum(:points)
Will yield a result like
{[2014, 4]=>3,
[2014, 8]=>7,
[2015, 4]=>26,
[2015, 6]=>19,
[2015, 12]=>50,
[2015, 32]=>48,
[2016, 2]=>78,
[2016, 3]=>45,
[2016, 4]=>49,
[2016, 5]=>110,
[2016, 45]=>30,
[2017, 4]=>130,
[2017, 11]=>185}
where the key is [year, week], then you can use Date.commercial to get the week of
points_by_week.each do |(year, week), count|
date = Date.commercial(year, week)
puts "Week of #{date.strftime('%d/%m/%Y')} - #{count} total points"
end
And (just cause I can), the mysql version of the query looks like this
points_by_week = Log.where(user_id: user_id).group("year(created_at)", "week(created_at)").sum(:points)
This by default assumes the week starts on Monday, and the first week of a year is starts on the first Monday of the year
回答2:
something like:
points_by_week = Log.select("DATE_TRUNC('week', created_at) as week, sum(points) as total_points").group("week").where(user_id: x)
points_by_week.each do |pw|
puts "Week of #{pw.week.strftime('%d/%m/%Y')} - #{pw.total_points} total points"
end
EDIT
as per Michael Gorman comment the above won't distinguish between years (2017, 2016, etc), so you might need to group by week and year depending on your requirements:
Log.select("DATE_TRUNC('week', created_at) as week, DATE_TRUNC('year', created_at) as year, sum(points) as total_points").group("week, year")
and you can keep using the above loop to display it ;)
回答3:
Something like this:
select 'WEEK of ' || TO_CHAR(date_trunc( 'week', created_at ), 'dd/mm/yyyy') || ' - ' || sum(points) || ' total points'
FROM clients
WHERE id < 100000
GROUP BY date_trunc( 'week', created_at );
|| is used to concatenate string.
TO_CHAR is used as a data type formatting functions.
来源:https://stackoverflow.com/questions/44657770/with-rails-how-can-i-query-the-db-for-an-aggregate-number-and-grouped-by-week