【问题标题】:rails 3.2 / postgres - how cast SUM() to return an integer not string?rails 3.2 / postgres - 如何转换 SUM() 以返回整数而不是字符串?
【发布时间】:2014-06-24 20:12:35
【问题描述】:

像 SUM(foo) 这样的 Postgres 聚合返回一个字符串,即使 foo 是一个整数。

如何将总和转换为整数,以便生成的关系数组包含整数而不是字符串?

我尝试使用 ::integer 进行投射

Widget.select("SUM(points) as totalpoints::integer, agent, company")

但是 postgres 抛出错误 PG::Error: ERROR: syntax error at or near "::"

似乎应该有某种方法告诉 rails - 除了遍历每个返回的数组元素 - INT 的 SUM 是一个 INT?

【问题讨论】:

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


    【解决方案1】:

    这可能只是 ActiveRecord 适配器。不过,我对此并不完全确定。但我认为,当您深入到选择级别的 API 时,它只会返回字符串,因为它实际上是从数据库中读回的。当您使用更高级别的 API 时,我认为它知道如何将其转换回 Ruby 类型,因为它知道您的架构。

    我无法重现您上面的查询,但我执行了以下操作:

    Widget.connection.select_rows("SELECT sum(id) FROM widgets")
    

    返回:

    [
        [0] [
            [0] "887"
        ]
    ]
    

    如果我使用更高级别的 API:

    2.0.0-p353 :034 > Widget.sum('id')
    D, [2014-06-24T15:34:52.644852 #95176] DEBUG -- :    (0.5ms)  SELECT SUM("widgets."."id") AS sum_id FROM "widgets"
    887
    

    此时它在我的控制台中给了我一个整数类型。所以我怀疑 Postgres 没有什么问题,但是当你使用 ActiveRecord 选择 API 时,你可能需要自己转换为原生类型。

    【讨论】:

    • 你基本上是对的。 AR 并不真正了解它自己不编写的 SQL 类型的任何内容。
    • 是的,postgres 返回字符串。似乎应该可以以某种方式将其转换为查询中的 int 。现在我使用 .map() 迭代地将其强制为 int,但 SUMing ints 是一个非常基本的操作,似乎很难相信它不是一个简单的查询操作。
    • 不,你看错了。当您使用一些较低级别的 API 将您的查询传达给 postgres 时,实际上就像您在输入 psql 控制台一样。 Postgres 知道它是一个整数,但它基本上只是以与您在 psql 中获取相同的方式转储文本块。 Rails 不解析您传入的 SQL,因此它不知道响应的预期类型,因此它无法像往常一样自动转换。因此,由您自己进行转换。您不能只在 Postgresql 中进行 CAST; postgres 知道它是一个整数。 Rails 没有。
    猜你喜欢
    • 1970-01-01
    • 2018-11-16
    • 1970-01-01
    • 1970-01-01
    • 2014-04-21
    • 1970-01-01
    • 1970-01-01
    • 2014-11-15
    • 2021-03-02
    相关资源
    最近更新 更多