2013-08-29 70 views
2

有沒有更好地優化此函數中的查詢的方法?如果可能的話,我希望它只做一個SQL查詢。該代碼將獲取2周內生成的事件數量。謝謝。優化SQL查詢,檢索一段時間內的項目數

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 
+0

對我以前的文章做過我以前的評論工作 –

回答

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次相比),此代碼應該非常快。

+0

無論如何,它顯示0天的天數?我需要每天的數據點(包括0)。我原來的方法太慢了,因爲我的數據庫每週平均有200萬條記錄。 – Kidada

+0

如果您的數據庫每週獲得200萬條記錄,我覺得很難相信有0天的日子......無論如何,我更新了我的答案。 – Mischa

+0

感謝您的幫助。我遇到了h.value的一些問題,但你的方法給了我一個好主意。我將activerecord複製到一個散列,並使用「item_count:(items_hash.has_key?(date))?items_hash [date]:0.解決了問題。再次感謝。 – Kidada

-1

只是想刪除map迭代器的使用只是簡單

def items_chart_data 
    @item_count = Item.where("created_at >= ? AND created_at <= ? AND student_id = ?", 2.weeks.ago.to_datetime, Datetime.now, current_user.student_id).count 
    end 
+0

current_student是持有當前學生的變量。我正在使用current_student.id來引用所選學生的ID。我發佈的代碼正在工作。它會創建14個SQL查詢(2周內每天有1個查詢)。我正在尋找一種方法,以減少查詢的數量只是1. – Kidada

+0

看看我的帖子完成不使用地圖使用BETWEEN AND sql語句獲取該值內的數據 –

+0

@Kidada如果它在工作請給我投票 –