我正在一个学校项目中,我有表class_standard
和enrollments
enrollments
属于class_standard
,而class_standard
有许多enrollments
。
enrollments
是在不同的日期创建的。我想获取过去30天内阵列中的每日报名人数。
即[第一天,第二天,第三天.....的报名人数]
答案 0 :(得分:0)
这是代码示例,可获取创建的每日注册计数并将其存储在数组中。
arr = [] #initialize an array
(0..29).each do |x| #run a loop for 30 days
date = Time.now - x.days #get a specific day
arr << Enrollment.where(created_at: date.midnight..date.end_of_day).count #get count of enrollments on a specific day and add this to your array
end
arr = arr.reverse #reverse the array, because you want the today's count as last item of the array
答案 1 :(得分:0)
您要执行的操作是选择按天分组的计数。如何准确实现这一目标取决于所使用的数据库。
Postgres:
date_trunc('day', created_at)
MySQL:
date_format(created_at, '%Y-%m-%d')
对于其他数据库,请查阅文档中有关日期函数的信息。
您想要的查询总共是这样的:
SELECT
count(*) AS count,
date_trunc('day', created_at) AS day
FROM "enrollments"
WHERE (created_at >= ?) -- one month ago
GROUP BY day
ORDER BY day
我们可以在ActiveRecord中将其编写为:
Enrollment.select("count(*) AS count, to_char(created_at, 'YYYY-MM-DD') AS day")
.group("day")
.order("day")
.where(created_at: (1.month.ago..Time.current))
但是这提供了一个ActiveRecord :: Relations记录,这不是很有用。要获取原始查询值,我们要使用#select_all
。
sql = Enrollment.select("count(*) AS count, date_trunc('day', created_at) AS day")
.group("day")
.order("day")
.where("created_at >= ?", 1.month.ago)
.to_sql
results = Enrollment.connection.select_all(sql)
将结果转换为数组时,将获得一个哈希数组:
[{"count"=>10, "day"=>"2018-10-20 00:00:00"}, {"count"=>10, "day"=>"2018-10-21 00:00:00"}, {"count"=>10, "day"=>"2018-10-22 00:00:00"}, {"count"=>10, "day"=>"2018-10-23 00:00:00"}, {"count"=>10, "day"=>"2018-10-24 00:00:00"}, {"count"=>10, "day"=>"2018-10-25 00:00:00"}, ...]
您可以通过映射数组来提取计数:
results.map {|r| r["count"] }
如果只希望一个(或多个)ClassStandards的结果,只需在where子句中添加一个附加条件:
sql = Enrollment.select("count(*) AS count, date_trunc('day', created_at) AS day")
.group("day")
.order("day")
.where("created_at >= ?", 1.month.ago)
.where(class_standard: @class_standard)
.to_sql
或者您将其取消关联:
sql = @class_standard.enrollments
.select("count(*) AS count, date_trunc('day', created_at) AS day")
.group("day")
.order("day")
.where("created_at >= ?", 1.month.ago)
.to_sql
答案 2 :(得分:0)
如果您想计算所有天数,包括没有注册的天数:
daily_enrollments = []
i = 29
while i >= 0
daily_enrollments >> Enrollments.where( created_at: Time.zone
.now
.beginning_of_day-i.day..
Time.zone
.now
.end_of_day-i.day).count
i = i-1
end
输出示例
[0,0,0,5,4,0,0,0,5,0,23,0,0,23,0,0,1,0,11,0,21,32,44,0,0,9,6,3,22,1]
这将为您提供所有30天的阵列。但这似乎不是有效的代码。每个记录将运行30个查询。
对我来说更好的方法是将记录分组在created_at
上,并获取具有某些记录的日期的记录。即排除无记录的天。
Enrollments.where(created_at: Time.current - 30.days..Time.current)
.group("date(created_at)")
.count
.sort
.to_h
输出示例
{Mon, 19 Nov 2018=>12}