在 rails 查询中为日期列设置新的年份
Set new year for date column in rails query
我有许多公司的合同开始时间,我想通过创建一个合同开始时间更新为 select 年的列来报告每个合同年度。 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")
我正在寻找一种解决方案,它可以:
- 直接把年份设置成我想要的
- 根据与所需年份的距离添加可变数量的年份
我在 Ruby 2.3.3
我认为这里的关键是找到与我的数据库所基于的 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 代码需要读取字符串以将其转换为日期
可能还有其他方法可以直接“构建”日期,但这种方法目前效果很好。
我有许多公司的合同开始时间,我想通过创建一个合同开始时间更新为 select 年的列来报告每个合同年度。 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")
我正在寻找一种解决方案,它可以:
- 直接把年份设置成我想要的
- 根据与所需年份的距离添加可变数量的年份
我在 Ruby 2.3.3
我认为这里的关键是找到与我的数据库所基于的 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 代码需要读取字符串以将其转换为日期
可能还有其他方法可以直接“构建”日期,但这种方法目前效果很好。