我有一个订单表格,其中包含order_date
日期时间列。需要一条查询语句,在特定时间范围内获取所有日期的记录。
例如:获取在东部时间上午7点至9点之间所有日期的订单。
类似于:
Order.where('time(order_date) BETWEEN ? AND ?', '7am', '9am')
开始和结束时间来自文本字段,用户可以输入2am、3pm、6am等字符串值。
我有一个订单表格,其中包含order_date
日期时间列。需要一条查询语句,在特定时间范围内获取所有日期的记录。
例如:获取在东部时间上午7点至9点之间所有日期的订单。
类似于:
Order.where('time(order_date) BETWEEN ? AND ?', '7am', '9am')
开始和结束时间来自文本字段,用户可以输入2am、3pm、6am等字符串值。
EXTRACT
你可以使用EXTRACT
从order_date
中获取小时数:
Order.where('EXTRACT(hour FROM order_date) BETWEEN ? AND ?', 7, 20)
20
(晚上8点)指定为上限。如果我使用21
,那么具有21:30时间组件的order_date
将匹配,这不是我们想要的。class Order < ActiveRecord::Base
scope :between, -> (start_hour, end_hour) {
where('EXTRACT(hour FROM order_date) BETWEEN ? AND ?', start_hour, end_hour - 1)
}
end
还有一些其他问题需要考虑,例如检查start_hour
和end_hour
是否具有有效值(例如-1小时是无效的)。
这种方法很简单,但仅限于整点(您可以添加分钟和秒,但该方法会变得复杂)。
time
Ruby
中的Time
存储日期和时间。例如:
Time.parse('15:30:45') # => 2017-01-02 15:30:45 +0100
Time
传递给PostgreSQL,并将其显式转换为Postgres time
类型:class Order < ActiveRecord::Base
scope :between, -> (start_time, end_time) {
where('order_date::time BETWEEN ?::time AND ?::time', start_time, end_time)
}
end
这种方法的优点是灵活性。缺点是在处理 UI 中的时间时会更加复杂。范围 (scope) 需要一对 Time
对象。有许多获取它们的方法,例如:Time.parse('12:17')
。
Order.where('order_date < ?', Time.now).where('order_date > ?', Time.now - 1.month)
如果您需要将类似于"9am"
的字符串转换为对象,则可以使用Time#parse
。
irb(main):006:0> Time.parse('9 AM')
=> 2016-12-27 09:00:00 -0700
morning = Time.parse('9 AM')
# 2016-12-27 09:00:00 -0700
night = Time.parse('10 PM')
# 2016-12-27 22:00:00 -0700
Order.where('order_date > ?', morning).where('order_date < ?', night)
Order Load (0.2ms) SELECT `orders`.* FROM `orders ` WHERE (order_date > '2016-12-27 16:00:00.000000') AND (order_date < '2016-12-28 05:00:00.000000')
Order.where(order_date: Time.parse("7am")..Time.parse("9am"))
Time
既是日期又是时间。我在本地测试了它是不正确的。生成的查询是SELECT "teachers".* FROM "teachers" WHERE ("teachers"."created_at" BETWEEN $1 AND $2)
,并且被替换为[["created_at", 2017-01-03 06:00:00 UTC], ["created_at", 2017-01-03 08:00:00 UTC]]
。您的查询选择了今天上午7点到9点之间下的订单。@Arif需要任何一天下的订单。 - Greg NavisHOUR
函数:
Order.where("HOUR(order_date) between 7 and 9")