是否可以将活动记录查询与postgreSQL原始查询相结合

时间:2014-12-10 02:54:19

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

是否可以将活动记录查询与postgreSQL原始查询相结合?

Czce.where(“time>?”,“2014-02-09”.to_datetime).raw_query

  def self.raw_query
    raw_q = 'SELECT cast(ticktime as timestamp(1)) AS ticktime
              ,max(bid_price) as price, max(bid_volume) as volume
              From  czces
              Group BY 1
              ORDER BY 1
              limit 1000;'
    ActiveRecord::Base.connection.select_all(raw_q)
  end

如果我使用find_by_sql执行此操作,则数据库的结果会丢失许多列。

条件.where("ticktime > ? ", "2014-02-09".to_datetime)仍然不起作用

这是查询表达式Czce.where("ticktime > ? ", "2014-02-09".to_datetime).find_by_sql(raw_q)

[998] #<Czce:0x007fc881443080> {
          :id => nil,
    :ticktime => Fri, 07 Feb 2014 01:16:41 UTC +00:00
},
[999] #<Czce:0x007fc881442d38> {
          :id => nil,
    :ticktime => Fri, 07 Feb 2014 01:16:42 UTC +00:00
}

但预期结果应包含pricevolume

from (pry):3:in `block (2 levels) in <top (required)>'
[4] pry(main)> result[0]
{
    "ticktime" => "2014-02-28 07:00:00",
       "price" => "7042",
      "volume" => "2"
}
[5] pry(main)> result[1]
{
    "ticktime" => "2014-02-28 06:59:59",
       "price" => "18755",
      "volume" => "525"
}

2 个答案:

答案 0 :(得分:2)

简而言之,没有。

原始select_all查询以发送到服务器的纯 SQL 完成,并将记录作为原始数据发回。

来自select_all的Rails指南(强调我的):

  

select_all将使用自定义 SQL 从数据库中检索对象   就像find_by_sql一样,但不会实例化它们。相反,你会的   获取一个散列数组,其中每个散列表示一条记录。

您可以迭代生成的记录并对其执行某些操作,可能将它们存储在您自己的类中,然后通过 ActiveRecord 在后续调用中使用该信息,但您实际上无法直接链接二。如果您打算使用原始 SQL (当然有很多原因可能需要这样做),您也可以在相同的上下文中同时获取所需的所有其他内容。时间,在同一个原始查询中。

还有find_by_sql,它将返回实例化 ActiveRecord 对象的数组。

从指南中:

  

find_by_sql方法将返回一个对象数组,即使它是   基础查询只返回一条记录。

  

find_by_sql为您提供了一种简单的自定义调用方式   数据库和检索实例化对象。

然而,这是一个实际的实例化对象,虽然在许多方面可能更容易,因为它们将被映射到模型的一个实例而不仅仅是一个哈希,链接,比如,where到那个不是正如通常所做的那样,与对基本模型类的链式调用相同。

我建议您在 SQL 本身,所有服务器端执行所有操作,然后您可以在Rails中通过迭代遍历客户端进行任何进一步的修饰过滤。返回的记录。

答案 1 :(得分:0)

尝试不使用基本连接本身,请尝试展开标准rails sql表单,如:

Czces.select("cast(ticktime as timestamp(1)) AS ticktime,max(bid_price) as price, max(bid_volume) as volume")
     .group("1").order("1").limit(1000)

但是如果你只是解释一个条件,即你真的想从查询中获取,我们将尝试编写一个合适的sql。