【问题标题】:Set new year for date column in rails query在 Rails 查询中为日期列设置新年
【发布时间】:2021-02-28 06:42:03
【问题描述】:

我有许多公司的合同开始时间,我想通过创建一个列来报告每个合同年份,并将合同开始时间更新为选定的年份。 SQL 中有许多解决方案涉及 DATE_ADD 或 DATEFROMPARTS 之类的函数,但我无法将其适应 rails(如果这些函数完全可用的话)。

我得到的最接近的是:Company.select("contract_start + '1 YEAR'::INTERVAL as new_contract_start")。这会使每个合同开始时间增加 1 年,但不考虑超过一年(或同年开始)的合同。我也尝试了以下方法,但再次遇到语法错误:

new_year = 2020
Company.select("contract_start + '#{new_year} - EXTRACT (YEAR from contract_start) YEAR'::INTERVAL")    

我正在寻找一种解决方案,可以:

  1. 直接将年份设置为我想要的
  2. 根据与所需年份的距离添加可变数量的年份

我正在使用 Ruby 2.3.3

【问题讨论】:

    标签: ruby-on-rails ruby sqlite datetime activerecord


    【解决方案1】:

    我认为这里的关键是找到与构建我的数据库的 PostgreSQL 兼容的函数。一旦我开始搜索我认为会有所帮助的函数及其 PostgreSQL 等效函数,我发现了更多兼容的解决方案,例如:NUMTODSINTERVAL in PostgreSQL

    我最终得到:

    contract_start_year = 2020
    Company.select("contract_start + make_interval(years => CAST (#{contract_start_year} - EXTRACT (YEAR from contract_start) as INT))
    

    我还通过在不超过报告日期的情况下添加获得最新合同日期所需的年数来使其更智能。如果报告开始日期是“2020-01-01”但合同开始日期是“2017-06-01”,这将是有问题的。将合同日期设置为“2020-06-01”会超出报告的意图。

    report_start = "`2020-07-01`"
    Company.select("contract_start + make_interval(years => CAST (EXTRACT (YEAR FROM AGE(CAST (#{start_quotations} AS DATE), contract_start)) AS INT)) as new_contract_year")
    

    注意report_start 中的附加单引号,因为 SQL 代码需要读取字符串才能将其转换为日期

    可能还有其他方法可以直接“构建”日期,但这些方法目前运行良好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-28
      相关资源
      最近更新 更多