2

この関数でクエリを最適化する方法はありますか? 可能であれば、単一の SQL クエリのみを作成したいと考えています。このコードは、2 週間にわたって生成されたイベントの数を取得します。ありがとう。

def items_chart_data
    @current_student = Student.find(current_user.student_id)
    (2.weeks.ago.to_date..DateTime.now).map do |date|
        {
            created_at: date,
            item_count: Item.where("date(created_at) = ? AND student_id = ?", date, @current_student.id).count
        }
    end
end
4

1 に答える 1

1

次のように、1 つのクエリで実行できます。

items = Item.select('date(created_at) as date_created, count(id) as id_count').
          where('student_id = ? and created_at >= ?', current_user.student_id, 2.weeks.ago.beginning_of_day).
          group('date(created_at)').map do |item|
  { created_at: item.date_created, item_count: item.id_count }
end

欠落している日付を配列に 0 個のアイテムで取得するには、次のようにします。

(2.weeks.ago.to_date..Date.current).each do |date|
  date = date.strftime('%Y-%m-%d')

  unless items.any? { |h| h.value?(date) } # Check if date exists already
    items << { created_at: date, item_count: 0 } # Add item_count: 0 if not
  end
end

items.sort_by! { |h| h[:created_at] } # Put array in correct order

ゼロ項目日を配列に追加しても、クエリは実行されないことに注意してください。配列itemsには 14 個の要素しか含まれていないため、(特にデータベースに 14 回クエリを実行する場合と比べて) このコードは非常に高速です。

于 2013-08-29T07:17:17.063 に答える