【问题标题】:Rails ActiveRecord - how to fetch records between two datesRails ActiveRecord - 如何获取两个日期之间的记录
【发布时间】:2012-09-13 10:38:10
【问题描述】:

我在数据库表中有两个日期列 - from_dateto_date

例子:

  • from_date: 2012-09-10
  • to_date: 2012-09-30
  • today: 2012-09-13

如果today 的日期在from_dateto_date 之间,我需要获取所有记录。如何使用 SQL 查询做到这一点?

如果我已经加载了相应的记录,我可以很容易地确定今天的日期是否在from_dateto_date 之间,但我不知道如何直接从数据库表中获取这些记录。

【问题讨论】:

标签: sql ruby-on-rails postgresql activerecord


【解决方案1】:

检查范围条件下的Rails guides

Client.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)

这将产生以下 SQL:

SELECT * FROM clients WHERE (clients.created_at BETWEEN '2008-12-21 00:00:00' AND '2008-12-22 00:00:00')

【讨论】:

  • 这实际上并没有回答所提出的问题。他想知道日期何时介于两个单独列的值之间,这就是列位于两个日期之间的位置。
  • 这实际上并没有回答所提出的问题。
【解决方案2】:
data = ModelName.where("today >= from_date AND today <= to_date")

【讨论】:

  • 这个答案实际上比保罗的更笼统。 Paulo 的查询假设您有一个字段(created_at在他的回答中),您希望在两个日期之间有一个字段。如果我想看看今天是否在start_dateend_date 之间呢?保罗的回答无法做到这一点。
【解决方案3】:

一种安全且简单的方法是:

Model.where(':date BETWEEN from_date AND to_date', date: Date.current)

【讨论】:

  • 您可以使用"?",而无需传递包含绑定值的哈希(Model.where('? BETWEEN from_date AND to_date', Date.current))。更短的是,您可以依赖 RDBMS 提供的功能; Model.where('DATE_CURRENT BETWEEN from_date AND to_date')(特定于 pg)。
  • 我知道...我更喜欢传递哈希,因为它更容易理解并且读起来像一个句子。至于当前日期依赖数据库,是的,您可以,但是您在数据库时区而不是 Rails 应用程序/用户会话的时区中进行查询。
【解决方案4】:

你可以这样使用:

Data = Model.where("date(now()) between from_date and to_date")

【讨论】:

    【解决方案5】:
    data = ModelName.find(:all, :conditions => "today >= from_date and today <= to_date")
    

    【讨论】:

      【解决方案6】:

      这应该可以解决问题。

      today = Date.today
      
      data = ModelName.where("from_date <= ? AND to_date >= ?", today, today)
      

      【讨论】:

        【解决方案7】:

        您可以使用下面的 gem 来查找日期之间的记录,

        这个 gem 很容易使用和更清晰By star 我正在使用这个 gem,API 更清晰,文档也得到了很好的解释。

        ModelName.between_times(Time.zone.now - 3.hours,  # all posts in last 3 hours
                          Time.zone.now)
        

        在这里你也可以通过我们的领域ModelName.by_month("January", field: :updated_at)

        请查看文档并尝试一下。

        【讨论】:

          【解决方案8】:

          好的,在谷歌长时间搜索后,寻找一种“rails 方式”来执行 BETWEEN 与两个日期字段和一个变量,我发现最近似的解决方案是创建你自己的 scope 来做到这一点。

          在你的 ApplicationRecord 中写:

          class ApplicationRecord < ActiveRecord::Base
          
            scope :between_fields, -> (value, initial_date, final_date) { 
              where "('#{value}' BETWEEN #{initial_date} AND #{final_date})"
             }
          
          end
          

          所以现在,无论您需要做什么,都可以:

          @clients = Client.between_fields(params[:date], :start_date, :final_date)
          # SELECT * FROM clients WHERE ('2017-02-16 00:00:00' BETWEEN start_date AND final_date)
          

          您可以将它与其他“在哪里”结合起来,根据需要进行具体查询。

          【讨论】:

          • 作用域是实现此目的的好方法,但使用字符串插值对于安全性来说是个坏主意。您不应该在查询中使用 `#{string}` 语法,尤其是当您直接从参数传递时!
          • 这意味着要请求一列,而问题清楚地说明了两列; from_dateto_date.
          猜你喜欢
          • 2019-03-14
          • 1970-01-01
          • 2012-10-17
          • 2013-04-16
          • 2016-08-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多