我有每1小时提供一次降雨的数据。我面临的问题是它记录了从第二天上午9点到8:30点的降雨量。如何在Rails 5中使用Postgres最好地查询此特定时间范围?
到目前为止,我将按照时间戳(即日期和时间)分组,并选择上午9点的开始时间,但是我没有达到的目标是通知查询要在第二天上午8:30之前到达降雨数据将在第二天刷新。
@rainfall = Weather.select('DATE(timestamp) as timestamp, MAX(rain) as maxrain')
.group(:timestamp).where("timestamp::time BETWEEN '9:00:00' AND '8:30:00'")
答案 0 :(得分:0)
知道您的一天从9:00开始,到第二天的8:30结束,因此最好为数据设置范围。
示例:
scope :for_day, -> (day) {
date_time_from = Time.zone.parse("#{day.strftime('%Y-%m-%d')} 9:00")
date_time_to = Time.zone.parse("#{(day + 1.day).strftime('%Y-%m-%d')} 8:30")
where(timestamp: (date_time_from..date_time_to))
}
用法:
Weather.for_day(1.day.ago)
将返回:08 May 2019 9:00 AM till 09 May 2019 8:30 AM
然后您就可以对数据进行任何操作(例如:group和max)
基于注释,我假设您想获取所有数据。话虽这么说,最好将新的列添加到您的表中。
add_column :weathers, :day
add_index :weathers, :day
class Weather < ApplicationRecord
before_save :set_date
scope :for_day, -> (day) {
where(day: day)
}
def self.dates_for_day(day)
date_time_from = Time.zone.parse("#{day.strftime('%Y-%m-%d')} 9:00")
date_time_to = Time.zone.parse("#{(day + 1.day).strftime('%Y-%m-%d')} 8:30")
return {
day: day,
from: date_time_from,
to: date_time_to
}
end
private
def set_day
# get the surrounding days to know which day to use
surrounding_days = [
Weather.dates_for_day(self.timestamp - 1.day),
Weather.dates_for_day(self.timestamp),
Weather.dates_for_day(self.timestamp + 1.day),
]
self.day = surrounding_days.select { |d| self.timestamp.between?(d[:from], d[:to]) }.first[:day]
end
end
现在,您可以按照所需的方式对数据进行查询/分组