在Rails中日期范围内每天计算记录数的有效方法,无需每天进行一次查询

时间:2017-08-15 02:45:57

标签: mysql sql ruby-on-rails

使用import java.util.*; public class StackPostfixEva { public static void main(String args[]) { Scanner key = new Scanner(System.in); char[] postfix = new char[10]; System.out.println("Please enter postfix expression. " + "Enter '#' if you have finish entering postfix expression"); int i; for (i = 0; i <= 9; i++) { postfix[i] = key.next().charAt(0); if (postfix[i] == '#') { break; } } System.out.println("The postfix expression are:"); for (i = 0; i <= 9; i++) { System.out.println(postfix[i]); } Stack<Integer> st = new Stack<>(); int result, ch1, ch2; for (i = 0; i <= postfix.length; i++) { if (postfix[i] >= '0' && postfix[i] <= '9') { st.push(postfix[i] - '0'); } else { ch1 = st.pop(); ch2 = st.pop(); switch (postfix[i]) { case '+': result = ch2 + ch1; break; case '-': result = ch2 - ch1; break; case '*': result = ch2 * ch1; break; case '/': result = ch2 / ch1; break; case '%': result = ch2 / ch1; break; default: result = 0; } st.push(result); } } result = st.pop(); System.out.println(result); } } 的Rails应用生成一个预订日历,每天显示签到签出正在进行中 fullcalendar.js 每个日期

这是一个样本结果:

enter image description here

使用SQL我可以按reservationscheck-in对预订进行分组,并轻松生成每天计数的JSON(因为这两个日期 - 签入和签出 - 是实际的数据库中的列)。所需要的只是2个查询(一个用于签到,另一个用于结账)。

但我不知道如何处理check-out计数,因为日期不在数据库中,是in progressvoid日期之间的check_in

我当前的解决方案(我能想到的唯一解决方案)需要循环遍历日历的每个check_out并为day的预留发出SQL计数,但需要大量的SQL查询(日历视图中每天一个)。这是当前的工作代码:

check_in < day AND check_out > day

是否有办法构建# Start_date and end_date are provided by 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 do |day| count = current_user.reservations.where("DATE(check_in) < :date AND DATE(check_out) > :date", date: day).size if count > 0 # If the count > 0, there's an active reservation on this day. If the # count changed when compared to the previous day, we create a new event # on fullcalendar (to change the `title` of the event with the new count). # If the count remained the same as the previous event, we can just update # it's end date to the current date being analyzed so se get a nice UI # (continuous event while the count doesn't change instead of one event # per day) if last_in_progress_event && last_in_progress_event[:count] == count # Day + 1 is required due to fullcalendar.js cutting the event short one 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 的哈希值,每月不超过30次查询?

1 个答案:

答案 0 :(得分:0)

你可以试试这样的吗?

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 ALL ",""),"(SELECT '", m_CheckDate,
                              "' AS CheckDate )");
      SET m_Counter = m_Counter + 1;
      IF m_Counter < DATEDIFF(m_DateTo, m_DateFrom)+1 THEN
          ITERATE CreateDates;
      ELSE
          LEAVE CreateDates;
      END IF;

    END LOOP CreateDates;
    SET @m_SQLInProgress = CONCAT("SELECT v.CheckDate, Count(*) InProgressCount FROM (",m_SQLDates,") v ",
                                  "LEFT JOIN yourtable t ON t.check_in < v.CheckDate AND ",
                                  "t.check_out > v.CheckDate GROUP BY v.CheckDate"); 

    PREPARE m_SQLDates FROM @m_SQLInProgress;
    EXECUTE m_SQLDates;
    DEALLOCATE PREPARE m_SQLDates;
END

根据您的要求修改代码。一直玩它,直到你得到你想要的输出。