2012-07-17 60 views
2

計數統計我有一個表的模型圖:生成按小時,天,月,年

View(id: integer, created_at: datetime) 

我想一定時間內產生每小時,天,月或年觀看次數的時間在圖表上使用它們。我已經在做這樣的事情:

View.group('DATE(views.created_at)') 
    .select("*, count(*) AS series_count, DATE(views.created_at) AS series_time") 
    .where(:created_at => (Time.now-7.days)..Time.now) 

這導致:

2012-06-16 => 20 
2012-06-17 => 12 
2012-06-18 => 15 
2012-06-20 => 38 # Issue: Didn't include a day with no records 
2012-06-21 => 11 
2012-06-22 => 76 
  1. 的第一個問題是,它不添加填充到subtitute幾天或者幾個月或者沒有任何記錄。

  2. 第二個問題是,有時它增加了另一天導致8天!

  3. 第三個問題是,當我嘗試顯示每小時和其他時間週期的計數時,它會變得非常棘手,有人可以提出一個更好的解決方案,適用於其他日間循環嗎?

基本上我做的是被包含在所有的模型一樣方便統計生成模塊時間表:

include Timeline # on the model 
Model.timeline(
     :time_column => :created_at, 
     :period => (Time.now-24.hours)..Time.now, 
     :by => :hours 
    ) 

謝謝!

+0

請指定您的DBMS。它是Postgres? – hgmnz 2012-07-17 18:13:33

+0

@hgimenez這是MySQL – Ryan 2012-07-17 20:16:44

回答

0

1)有很多方法可以解決這個問題,但我不確定哪個更有效。它們都包括首先製作一系列您想要顯示的日期,然後添加不在您的結果子集中的內容或將您從數據庫獲得的內容插入到地圖中。我做了類似的,使的預期時間的陣列而回一句:

class Time 

    #Period is the number of seconds between each interval 
    def upto(end_time, period) 

    division_count = (end_time.to_i - self.to_i)/period 

    divisions = division_count.times.map { |div| self + (period * div) } 

    divisions << end_time 

    end 

    #Period is the number of seconds between each interval 
    def downto(start_time, period) 

    division_count = (self.to_i - start_time.to_i)/period 

    divisions = division_count.times.map { |div| start_time + (period * div) } 
    divisions 

    end 

end 

拿到兩天之間的陣列,稱之爲如下:

time_one.upto(time_two, 1.day.to_i) 

警告:這將包括天。要有7天的時間範圍,請從time_two移除一天。

time_one.upto(time_two - 1.day, 1.day.to_i 

2)這個問題是,你需要的是當前時間而不是最後一小時。你需要回到最後一天/小時/分鐘,然後從中減去。對於天的範圍內,你可以做這樣的2012年4月:

Time.utc(2012, 04)..Time.utc(2012, 05) 

這將從午夜在四月的最後一天得到在四月的第一天到午夜。有效獲取該月份的所有數據。您可以通過刪除月份參數並在幾天內添加day參數來實現這一點。 See usage here.

幾個小時,它有點複雜。你可以做一個新的日期,只是將你想要保留的日期轉移到新的日期,從而剝離你不需要的東西,然後從中減去。

3)我已經做了一段時間,因爲我已經做了SQL,所以我不能真正給你這個確切的代碼,但你總是可以嘗試格式化日期輸出,所以它包括小時/分鐘/等當它分組時,它會知道。即使格式化爲一個字符串將工作。效率較低的方法是爲每個時間範圍分別撥打電話。

+0

感謝你的問題是,這可能不適用於每月週期,因爲顯然月可能有28,29,30或31天。 – Ryan 2012-07-17 16:21:45

+0

正如我在第3部分所說的,如果你只能得到你所在領域的月份,它會按月分組。我將編輯2以反映代碼之後的含義。 – Moox 2012-07-17 16:29:28

+0

另外'(Date.today.to_time - 7.days).. Date.today.to_time'仍然返回8天'Time.upto'。它使用:'2012-07-10 00:00:00 + 0100..2012-07-17 00:00:00 + 0100' – Ryan 2012-07-17 16:32:41