我应该为在Rails中返回大小数的sql使用什么postgres数据类型

时间:2015-08-12 14:47:23

标签: postgresql ruby-on-rails-4 bigdecimal

我有一个应用程序,我正在尝试将一个美元金额生成一个名为Metric的新AR记录。我编写了以下简单类方法来生成新的度量方法:

  def self.last_year
    m = Metric.new
    m.name = Figaro.env.company_name
    m.metric_type = "Last Year"
    m.amount = ActiveRecord::Base.connection.execute("select sum(dst_amt::DECIMAL) from distributions where dst_code like 'COL%' and dst_posted_date::DATE BETWEEN (select (date_trunc('month', current_date)) - INTERVAL '13 Month') and (select (date_trunc('month', current_date)) - INTERVAL '366 Day')")
    m.save
  end

这基本上可以工作并创建度量标准记录,但是在运行此方法后在控制台中输出它的数量是:

<BigDecimal:10173c470,'0.0',9(18)>

当我在Postico或Navicat raw中运行SQL时,结果的数字为:1043.88。所以我的问题是:

1。)基于此查询和原始结果,我应该在postgres中使用哪个数据类型的金额字段?我尝试了十进制,但它将输出写为BigDecimal,我无法读取它,我也尝试了浮点数,但是当我运行类方法时,它在类上给了我一个NoMethodError to_f

2。)这是从类中运行SQL的最佳方法吗?当我通过Navicat或Postico运行它时,我的SQL是正确的,但是在类I中输出一个大的十进制数。

我的最终目标是在多个服务器上生成度量标准记录,然后通过第二个dbase连接以某种方式将它们转移到目标服务器,或者只是导出到csv,scp over,并通过目标服务器上的csv导入。实际上这应该是一种API类型的场景,但我没有那种时间,并且需要在今天获得有用的东西。

如果我的代码和/或问题不明确,请告诉我,我会进行修改。

更新 因此,当我尝试在控制台中打破此方法时,我运行它:

a = ActiveRecord::Base.connection.execute("select sum(dst_amt::DECIMAL) from distributions where dst_code like 'COL%' and dst_posted_date::DATE BETWEEN (select (date_trunc('month', current_date)) - INTERVAL '13 Month') and (select (date_trunc('month', current_date)) - INTERVAL '366 Day')")

这给了我:=> #<PG::Result:0x0000010d84c958 status=PGRES_TUPLES_OK ntuples=1 nfields=1 cmd_tuples=1>

然后从控制台我调用a[0]我得到哈希值=> {"sum"=>"1101.88"}

所以我想我的问题已经扩大了。我是否正确地调用SQL来填充方法中的金额字段?如果是这样,我如何解析此输出以将十进制值1101.88(或任何结果)返回到作为十进制类型字段的金额列?

再次更新

这是我的重构方法

  def self.last_year_mtd
    m = Metric.new
    m.name = Figaro.env.company_name
    m.metric_type = "Last Year MTD"
    sql = ActiveRecord::Base.connection.execute("select sum(dst_amt::DECIMAL) from distributions where dst_code like 'COL%' and dst_posted_date::DATE BETWEEN (select (date_trunc('month', current_date)) - INTERVAL '13 Month') and (select (date_trunc('month', current_date)) - INTERVAL '366 Day')")
    total = sql[0]["sum"].to_s
    m.amount = total
    m.save
  end

因此,当我从控制台运行它时,它会创建一个新的Metric记录。因此,如果我创建两个记录,我需要对其进行算术运算。所以我试了一下。

从控制台中调出last_year_mtd和类似的方法,它具有不同的查询并生成不同的大小数。

然后我指定a = Metric.firstb = Metric.last来获取两个不同的对象。

然后我做算术:2.1.1 :012 > (b.amount - a.amount).to_s => "1396.4"

这看起来很有效。在算术上调用.to_s似乎已经成功了。

我确信这种方法可以更干净,所以如果有人对重构有想法,我会非常感激。

1 个答案:

答案 0 :(得分:1)

使用小数。

如果需要显示该值,则使用to_s将其转换为字符串,或使用to_f将其转换为float。但是有些小数不能准确地表示为浮点数,如果你想要做的只是查看值,那么字符串表示是合适的。