【问题标题】:How do I get MIN in Postgres to play nice with Rails?如何让 Postgres 中的 MIN 与 Rails 配合得很好?
【发布时间】:2014-10-28 15:35:06
【问题描述】:

现在,我正在 Rails 中运行一个庞大的查询:

@foo_collection = Foo.select('
    foos.id,
    array_agg() AS some_aggregate, -- about 20 of these, but they're not the problem
    MIN(bars.some_date), -- Returning wrong type - this is the problem
').joins('
    INNER JOIN bars... -- A LOT of joins - but also not the problem
').where('
    some_conditions
').group('
    foos.id
')

此查询根据 PGAdmin 提取我想要的数据。没有做的是很好地翻译成 Rails。尝试将@foo_collection.some_date 处理为DateTime 对象以创建时差会导致:

undefined method `-' for "2014-04-01 16:12:35.461712":String

有什么方法可以哄我的 PG 输出给 Rails 一个DateTime 而不是String,还是我必须告诉 Rails 将所有 some_dates 解析为 Strings?

到目前为止,我已经通过让 Rails 转换所有 @foo_collection.some_dates to_datetime,然后 to_f 来处理这个问题,这样我就可以找到它们之间的时间间隔。但这有很大的开销 - 如果我可以直接从数据库中提取一个 datetime 对象会容易得多。

【问题讨论】:

  • PostgreSQL 的聚合函数min() 不会改变其参数的数据类型。
  • 很奇怪。我在 rails 中编写的查询在模型类上使用 .joins、.where 和 .group。拉取字段 some_date 将返回 String。如果这不是 SQL 问题,那么为什么 Rails 拉的是 String 而不是 DateTime
  • 您可能想要编辑您的问题并粘贴到您的模型的代码中。还要尝试将您的查询减少到仍然显示奇怪行为的最低限度,并将其粘贴进去。作为 DBA,我会先检查 PostgreSQL 架构。
  • 不幸的是,除了一般结构之外,我无法透露我的数据库的详细信息。我会在这个限制范围内尽可能多地阐明这一点。
  • 您不需要分享您的数据库的详细信息。只需检查架构以确保 bar.some_date 列实际上已声明为日期。查看 PostgreSQL 架构本身,而不是您的模型。

标签: ruby-on-rails ruby ruby-on-rails-3 postgresql


【解决方案1】:

Rails 最有可能将字段作为字符串提取,因为您没有查询具有已定义列类型的模型,我认为您最好的选择可能是将查询更改为输出到表,然后使用 Rails 模型查询该表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-07
    • 2019-05-18
    • 2010-09-11
    • 1970-01-01
    • 2011-10-24
    • 2016-08-18
    • 1970-01-01
    • 2011-11-27
    相关资源
    最近更新 更多