mysql - Efficient way of counting number of records per day within date range in Rails without requiring one query per day -


rails app using fullcalendar.js generate reservation calendar shows, on each day, count of check-ins, check-outs , in progress reservations for each date.

this sample outcome:

enter image description here

using sql i'm able group reservations check-in , check-out , generate json count each day (since these 2 dates - check in , check-out - actual columns in database). takes 2 queries (one check-ins, 1 check-outs).

but don't know how handle in progress counts, since dates not in database, being void between check_in , check_out dates.

my current solution (the 1 think of) requires looping on each day of calendar , issuing sql count reservations check_in < day , check_out > day, takes lot of sql queries (one each day in calendar view). current working code:

# start_date , end_date provided fullcallendar.js params start_date, end_date = date.parse(start_date_string), date.parse(end_date_string)  # in progress last_in_progress_event = nil  array = []  (start_date..end_date).each |day|    count = current_user.reservations.where("date(check_in) < :date , date(check_out) > :date", date: day).size    if count > 0     # if count > 0, there's active reservation on day. if     # count changed when compared previous day, create new event     # on fullcalendar (to change `title` of event new count).     # if count remained same previous event, can update     # it's end date current date being analyzed se nice ui     # (continuous event while count doesn't change instead of 1 event     # per day)      if last_in_progress_event && last_in_progress_event[:count] == count       # day + 1 required due fullcalendar.js cutting event short 1 day       last_in_progress_event[:end] = (day + 1)     else       last_in_progress_event = {         title: "#{count} in progress",         start: day,         end: (day + 1),         allday: true,         classname: 'bgm-lightblue',         count: count       }        array.push(last_in_progress_event)     end    end # if count > 0  end  array 

would there way of building hash of {day: in_progress_count} without 30+ queries per month?

could try one?

create procedure `getinprogresscount`(m_datefrom date,                                        m_dateto date) begin      declare m_counter integer;     declare m_sqldates longtext;     declare m_checkdate date;     set m_counter = 0;     set m_sqldates = '';      createdates: loop       set m_checkdate = date_add(m_datefrom, interval m_counter day);       set m_sqldates = concat(m_sqldates, if(trim(m_sqldates) <> "", " union ",""),"(select '", m_checkdate,                               "' checkdate )");       set m_counter = m_counter + 1;       if m_counter < datediff(m_dateto, m_datefrom)+1           iterate createdates;       else           leave createdates;       end if;      end loop createdates;     set @m_sqlinprogress = concat("select v.checkdate, count(*) inprogresscount (",m_sqldates,") v ",                                   "left join yourtable t on t.check_in < v.checkdate , ",                                   "t.check_out > v.checkdate group v.checkdate");       prepare m_sqldates @m_sqlinprogress;     execute m_sqldates;     deallocate prepare m_sqldates; end 

modify code based on requirements. play until desired output.


Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -