我有一张表模型查看:
View(id: integer, created_at: datetime)
我想在一段时间内生成每小时,日,月或年的观看次数,以便在图表上使用它们。我已经做了类似的事情:
View.group('DATE(views.created_at)')
.select("*, count(*) AS series_count, DATE(views.created_at) AS series_time")
.where(:created_at => (Time.now-7.days)..Time.now)
这导致:
2012-06-16 => 20
2012-06-17 => 12
2012-06-18 => 15
2012-06-20 => 38 # Issue: Didn't include a day with no records
2012-06-21 => 11
2012-06-22 => 76
第一个问题是,它不会将填充添加到减去天数或月数或没有记录的任何内容。
第二个问题是,有时会增加另一天,导致8天!
第三个问题是,当我尝试显示每小时和其他时间周期的计数时,它变得非常棘手,有人可以建议一个更好的解决方案,但也适用于非日间周期吗?
基本上我正在创建一个模块时间轴,它包含在所有模型中,以便轻松生成数据:
include Timeline # on the model
Model.timeline(
:time_column => :created_at,
:period => (Time.now-24.hours)..Time.now,
:by => :hours
)
谢谢!
答案 0 :(得分:0)
1)有很多方法可以解决这个问题,但我不确定哪个更有效率。所有这些都包括首先制作一个您想要显示的日期数组,然后在结果子集中添加不包含的内容,或者将从数据库中获取的内容插入到地图中。我做了类似的事情,以便在一段时间内制作预期时间的数组:
class Time
#Period is the number of seconds between each interval
def upto(end_time, period)
division_count = (end_time.to_i - self.to_i) / period
divisions = division_count.times.map { |div| self + (period * div) }
divisions << end_time
end
#Period is the number of seconds between each interval
def downto(start_time, period)
division_count = (self.to_i - start_time.to_i) / period
divisions = division_count.times.map { |div| start_time + (period * div) }
divisions
end
end
要获取两天之间的天数,请按以下方式调用:
time_one.upto(time_two, 1.day.to_i)
警告:这将包括两天。要获得7天的续航时间,请从time_two中删除一天。
time_one.upto(time_two - 1.day, 1.day.to_i
2)这个问题是你需要花时间而不是最后一小时。你需要回到最后一天/小时/分钟,然后从中减去。对于天数之间的范围,您可以在2012年4月份这样做:
Time.utc(2012, 04)..Time.utc(2012, 05)
这将从四月的第一天午夜到四月的最后一天的午夜。有效获取该月的所有数据。您可以通过添加day参数来删除月份参数和数天来执行此操作多年。 See usage here.
几个小时,它有点复杂。您可以创建一个新的日期,只将您想要保留的日期转移到新日期,从而剥离您不需要的内容,然后从中减去。
3)自从我完成SQL以来已经有一段时间了,所以我无法真正为您提供相应的代码,但您可以随时尝试设置日期输出的格式,以便包括小时/分钟/等等。它会分组,它会知道的。即使将其格式化为字符串也行。一种效率较低的方法是为每个时间范围单独调用。