如何通过Rails 3中的时间片(总和,平均值,最小值,最大值等)获取聚合数据

ebe*_*and 9 sql postgresql activerecord ruby-on-rails ruby-on-rails-3

如何在Rails 3中创建由时间片聚合的活动关系查询?

我想建立一个查询,每隔n分钟可以为具有特定名称的计数器的每个样本返回min,max,avg,sum,count.

create_table "samples"  
    t.integer  "counter_id"  
    t.string "name"  
    t.float    "value"  
    t.datetime "created_at"  
end  
Run Code Online (Sandbox Code Playgroud)

fl0*_*00r 4

不幸的是我从未使用过 Postgres,所以这个解决方案适用于 MySQL。但我认为你可以找到 Postgres 的类似物。

class Counter < ActiveRecord::Base
  has_many :samples do
    # default 30 minutes
    def per_time_slice(slice = 30)
      start = "2000-01-01 00:00:00"
      self.select("*, 
                   CONCAT( FLOOR(TIMESTAMPDIFF(MINUTE,'#{start}',created_at)/#{slice})*#{slice},  
                     (FLOOR(TIMESTAMPDIFF(MINUTE,'#{start}',created_at)/#{slice})+1)*#{slice} ) as slice,
                   avg(value) as avg_value, 
                   min(value) as min_value, 
                   max(value) as max_value, 
                   sum(value) as sum_value, 
                   count(value) as count_value").
                   group("slice").order("slice")
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

用法

counter = find_some_counter
samples = counter.samples.per_time_slice(60).where(:name => "Bobby")
samples.map(&:avg_value)
samples.map(&:min_value)
samples.map(&:max_value)
Run Code Online (Sandbox Code Playgroud)

ETC

  • 将 CONCAT(bla, bla) 更改为 bla || bla 使其更受 PgSQL 喜爱。 (2认同)