Как получить агрегированные данные по срезу времени (сумма, среднее, минимальное, максимальное и т. Д.) В Rails 3 - PullRequest
9 голосов
/ 04 марта 2011

Как я могу создавать активные реляционные запросы в 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  

Ответы [ 2 ]

4 голосов
/ 11 марта 2011

К сожалению, я никогда не использовал 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

Использование

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)

и т. Д.

1 голос
/ 05 марта 2011

Это должно сработать:

Samples.where("SQL for the time slice goes here").where(:name, "Views").average(:value)

Вы также можете поменять среднее для любого из минимума, максимума и суммы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...