我想查询记录但是要指定术语。例如
Home.where(created_at: Time.parse("12pm")..Time.parse("4:00pm"))
此活动记录将从中午12:00到下午4:30获取所有记录。结果将是低于记录。
id | start_at
---+---------------------
1 | 2008-03-03 12:00:00
2 | 2008-03-04 12:10:00
3 | 2008-03-05 12:30:00
4 | 2008-03-08 12:50:00
5 | 2008-03-09 13:00:00
6 | 2008-03-10 13:10:00
7 | 2008-03-13 13:20:00
8 | 2008-03-14 13:50:00
9 | 2008-03-14 14:00:00
10 | 2008-03-14 14:10:00
11 | 2008-03-14 14:30:00
12 | 2008-03-14 14:50:00
13 | 2008-03-14 15:00:00
14 | 2008-03-14 15:30:00
15 | 2008-03-14 15:50:00
16 | 2008-03-14 16:00:00
17 | 2008-03-14 16:10:00
但我希望得到所有记录,但每1小时,如下面的结果。
id | start_at
---+---------------------
1 | 2008-03-03 12:00:00
5 | 2008-03-09 13:00:00
9 | 2008-03-14 14:00:00
13 | 2008-03-14 15:00:00
16 | 2008-03-14 16:00:00
然后如何查询活动记录?感谢。
答案 0 :(得分:1)
由于您选择PostgreSQL作为您的数据库,所以很幸运。使用extract
函数有一种非常简单的内置方法。
Home.where("extract(hour from created_at) BETWEEN :min AND :max", min: 12, max: 16)
.where("extract(minute from created_at) = 0")
如果这是你做了很多事情,也许稍微复杂一点的范围是有道理的:
class Home < ActiveRecord::Base
scope :hour_range, ->(min, max){
created_hour = Arel::Nodes::NamedFunction.new('extract', [Arel::Nodes::SqlLiteral.new('hour from "homes"."created_at"')])
where created_hour.between(min..max)
}
scope :top_of_hour, ->{
where Arel::Nodes::NamedFunction.new('extract', [Arel::Nodes::SqlLiteral.new('minute from "homes"."created_at"')]).eq(0)
}
end
是的,简单的Arel在没有ActiveRecord DSL的情况下是丑陋的,但它的功能更强大。我已经看到很多情况下你别无选择,只能在ActiveRecord的线之外进行着色,并且知道Arel在这些情况下真的有帮助。
答案 1 :(得分:0)
试试这个
24.times do |t|
result = Home.where(created_at: (Date.today.beginning_of_day+ (3600*t)))
puts result
end
答案 2 :(得分:-1)
您可能有一个棘手的时间为此创建查询。请记住,您的数据库可能会将时间/日期值存储为整数,并且不了解1728000和1814400在不同日期的同一时间,我们可能会将其视为&#34; 2016-05-04 12 PM&#34 ;和&#34; 2016-05-05 12 PM&#34;。
根据您的数据集,我看到两个可能的选项:
创建要使用
查询的值数组def query_hours(start_date, end_date, start_hour, end_hour)
cur_date = start_date
range = []
while cur_date <= end_date
if cur_date.hour >= start_hour && cur_date.hour <= end_hour
range << cur_date
end
cur_date += 3600
end
range
end
Home.where created_at: query_hours(
Date.new(2016, 5, 1),
Date.new(2016, 5, 31),
12,
16
)
这很麻烦,如果你只是查询当天的一小部分,那么它将会非常 效率低下。但是,您可以将其优化为仅在您的设定小时范围内循环。
我猜你最好的选择,老实说,会在你的Home模型中添加created_hour
属性,然后直接查询它。如果这是一个重要的查询,那么它是解决问题的最有效方法
# in your model class
class Home
after_commit :update_created_hour
def update_created_hour
if created_at.minute = 0 && created_at.sec == 0
self.created_hour = created_at.hour
else
self.created_hour = nil
end
save!
end
end
# to query
from = Time.parse("12pm").hour
to = Time.parse("8pm").hour
Home.where('created_hour >= ? AND created_hour <= ?', from, to)