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. 最初の問題は、レコードのない日や月などにパディングを追加しないことです。

  2. 2 つ目の問題は、別の日が追加されて 8 日になる場合があることです。

  3. 3 番目の問題は、1 時間あたりのカウントやその他のタイム サイクルを表示しようとすると、非常に扱いにくくなることです。

基本的に、次のような統計情報を簡単に生成するために、すべてのモデルに含まれるモジュール Timeline を作成しています。

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

ありがとう!

4

1 に答える 1

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

2 日間の日数の配列を取得するには、次のように呼び出します。

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

警告: これには両日が含まれます。7 日間の範囲にするには、time_two から 1 日を削除します。

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

2) この問題は、過去 1 時間ではなく現在の時間を取っていることです。最後の日/時間/分に戻ってから減算する必要があります。日の範囲については、2012 年 4 月の場合、次のようにすることができます。

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

これは、4 月 1 日の午前 0 時から 4 月の最後の日の午前 0 時まで取得されます。その月のすべてのデータを効果的に取得します。月の引数を削除するだけで何年も、日の引数を追加することでこれを行うことができます。使い方はこちらをご覧ください。

何時間もの間、それはもう少し複雑です。新しい日付を作成し、保持したいものだけを新しい日付に転送して、必要のないものを取り除き、そこから差し引くことができます。

3) SQL を実行してからしばらく経っているので、正確なコードを提供することはできませんが、いつでも日付出力をフォーマットして、時間/分/などを含めてグループ化することができます。 、それは知っているでしょう。文字列としてフォーマットしても機能します。効率の悪い方法は、時間範囲ごとに個別の呼び出しを行うことです。

于 2012-07-17T16:13:45.940 に答える