как посчитать запись в диапазоне дат вместе с ее критериями

0

У меня есть две базы данных:

Reservation
------------------------------------------------
| ID | RoomID | RoomName | BookingDate         |
|-----------------------------------------------
| 1  | 77     | Gold     | 2017-12-05 00:00:00 |
| 2  | 88     | Crystal  | 2017-12-11 00:00:00 |
| 3  | 88     | Crystal  | 2017-12-20 00:00:00 |
| 4  | 99     | Diamond  | 2017-12-01 00:00:00 |
| 5  | 77     | Gold     | 2017-12-04 00:00:00 |
| 6  | 77     | Gold     | 2017-12-15 00:00:00 |
-------------------------------------------------

Room
-----------------
| ID | RoomName |
-----------------
| 77 | Gold     |
| 88 | Crystal  |
| 99 | Diamond  |
-----------------

Я попытался подсчитать количество записей в комнате в пределах диапазона даты. Предполагалось, что выход будет:

------------------------------------------------------
| Date                    | Gold | Crystal | Diamond | 
------------------------------------------------------
| 1.12.2017 - 3.12.2017   |  0   |    0    |   1     |
| 4.12.2017 - 10.12.2017  |  2   |    0    |   0     |
| 11.12.2017 - 17.12.2017 |  1   |    1    |   0     |
| 18.12.2017 - 24.12.2017 |  0   |    1    |   0     |
| 25.12.2017 - 31.12.2017 |  0   |    0    |   0     |
------------------------------------------------------

Мое кодирование выглядит следующим образом:

<table>
<tr><th> Date </th>
    <?php
     $sql = mysql_query("SELECT * FROM Room", $con);
     while($record = mysql_fetch_array($sql)) {
    ?>
    <td> <?php echo $record['RoomName']?> </td>
    <?php
     }
    ?>
</tr>
<tr> <td>
     <?php
    $week = date("W", strtotime($_GET['Year'] . "-" . $_GET['Month'] ."-01")); // weeknumber of first day of month
    $startRange = date("d.m.Y", strtotime($_GET['Year'] . "-" . $_GET['Month'] ."-01")); // first day of month
    echo $startRange . " to "; 
    $unix = strtotime($_GET['Year']."W".$week ."+1 week");
    while(date("m", $unix) == $_GET['Month']){ // keep looping/output of while it correct month
        $endRange = date("d.m.Y", $unix-86400);
        echo $endRange . "</td>"; // Sunday of previous week

        //counting for Gold Room
        $res=mysql_query("SELECT * FROM Reservation WHERE (BookingDate>='".$startRange."' AND BookingDate<='".$endRange."') AND RoomID='77' ");
        $count=mysql_num_rows($res);
        echo "<td align='center'>" . $count . "</td>";
        //end counting part

        //counting part Crystal Room
        $res=mysql_query("SELECT * FROM Reservation WHERE (BookingDate>='".$startRange."' AND BookingDate<='".$endRange."') AND RoomID='88' ");
        $count=mysql_num_rows($res);
        echo "<td align='center'>" . $count . "</td>";
        //end counting part

       //counting part Diamond Room
       $res=mysql_query("SELECT * FROM Reservation WHERE (BookingDate>='".$startRange."' AND BookingDate<='".$endRange."') AND RoomID='99' ");
      $count=mysql_num_rows($res);
      echo "<td align='center'>" . $count . "</td>";
      //end counting part

      echo "</tr><tr> <td align='center'>";

      $lastStartRange = date("d.m.Y", $unix);
      echo $lastStartRange ." to "; // this week monday
      $unix = $unix + (86400*7);
     }

   $lastEndRange = date("t.m.Y", strtotime($_GET['Year'] . "-" . $_GET['Month']));
   echo $lastEndRange; //echo last day of month
   ?>
   </td> <td align="center">
   <?php
   //counting for Gold Room
   $res=mysql_query("SELECT * FROM Reservation WHERE (BookingDate>='".$lastStartRange."' AND BookingDate<='".$lastEndRange."') AND RoomID='77' ");
    $count=mysql_num_rows($res);
    echo "<td align='center'>" . $count . "</td>";
    //end counting part

    //counting part Crystal Room
    $res=mysql_query("SELECT * FROM Reservation WHERE (BookingDate>='".$lastStartRange."' AND BookingDate<='".$lastEndRange."') AND RoomID='88' ");
    $count=mysql_num_rows($res);
    echo "<td align='center'>" . $count . "</td>";
    //end counting part

    //counting part Diamond Room
    $res=mysql_query("SELECT * FROM Reservation WHERE (BookingDate>='".$lastStartRange."' AND BookingDate<='".$lastEndRange."') AND RoomID='99' ");
    $count=mysql_num_rows($res);
    echo "<td align='center'>" . $count . "</td>";
    //end counting part
  ?>

Проблема с приведенным выше кодом заключается в том, что, когда я выберу month = January, он отобразит диапазон дат 01.01.2017 - 31.12.2017. Что касается подсчета записей, это не соответствует записи в таблице базы данных Reservation. Я не знаю, как упростить код. Любое предложение или решение моей проблемы?

  • Месяц и Год для диапазона дат извлекаются из $_GET['Month'] и $_GET['Year']. Диапазон дат должен динамически меняться в зависимости от выбранного месяца и года..
  • Диапазон дат - диапазон недели для любого выбранного месяца, поэтому нет фиксированного диапазона недели.
  • Имя комнаты в заголовке таблицы следует извлекать из таблицы базы данных "Комната".
  • Подсчет должен подсчитывать количество бронирования для конкретного номера, находящегося в диапазоне дат.

Спасибо..

Теги:
count

5 ответов

0

все в порядке, ребята. Я уже получил решение. Спасибо всем за ваши усилия.

Вот мой ответ

<table>
<thead>
    <td colspan="12"> <label>Month: </label>
        <select name="chooseMonth" onChange="location='?Month=' + this.value">
        <option value="1" <?php if($_GET['Month'] == '1') { echo "selected"; } ?>>January</option>
        <option value="2" <?php if($_GET['Month'] == '2') { echo "selected"; } ?>>February</option>
        <option value="3" <?php if($_GET['Month'] == '3') { echo "selected"; } ?>>March</option>
        <option value="4" <?php if($_GET['Month'] == '4') { echo "selected"; } ?>>April</option>
        <option value="5" <?php if($_GET['Month'] == '5') { echo "selected"; } ?>>May</option>
        <option value="6" <?php if($_GET['Month'] == '6') { echo "selected"; } ?>>June</option>
        <option value="7" <?php if($_GET['Month'] == '7') { echo "selected"; } ?>>July</option>
        <option value="8" <?php if($_GET['Month'] == '8') { echo "selected"; } ?>>August</option>
        <option value="9" <?php if($_GET['Month'] == '9') { echo "selected"; } ?>>September</option>
        <option value="10" <?php if($_GET['Month'] == '10') { echo "selected"; } ?>>October</option>
        <option value="11" <?php if($_GET['Month'] == '11') { echo "selected"; } ?>>November</option>
        <option value="12" <?php if($_GET['Month'] == '12') { echo "selected"; } ?>>December</option>
        </select>
        &nbsp;&nbsp;&nbsp;&nbsp;
        <label>Year: </label>
        <select name="chooseYear" onChange="location='?Month=<?php echo $_GET['Month']?>&Year=' + this.value">
        <option value="2013" <?php if($_GET['Year'] == '2013') { echo "selected"; } ?>>2013</option>
        <option value="2014" <?php if($_GET['Year'] == '2014') { echo "selected"; } ?>>2014</option>
        <option value="2015" <?php if($_GET['Year'] == '2015') { echo "selected"; } ?>>2015</option>
        <option value="2016" <?php if($_GET['Year'] == '2016') { echo "selected"; } ?>>2016</option>
        <option value="2017" <?php if($_GET['Year'] == '2017') { echo "selected"; } ?>>2017</option>
        <option value="2017" <?php if($_GET['Year'] == '2018') { echo "selected"; } ?>>2018</option>
        <option value="2017" <?php if($_GET['Year'] == '2019') { echo "selected"; } ?>>2019</option>
        </select>
    </td>
</thead>
<tr style="background-color: #ddd;">
    <th> Date </th>
    <?php 
        $sql = mysql_query("SELECT * FROM Rooms WHERE Status='T'", $mrrs);
        while ($rec = mysql_fetch_array($sql)) {
            $RoomName = $rec['Room_Name'];
    ?>
        <td align="center"> <?php echo $RoomName; ?> </td>
    <?php } ?>
</tr>
<tr>
    <td align="center">
    <?php
    $endDate = date("t", strtotime($_GET['Year']."-".$_GET['Month']."-01"));

    $dayOfWeekOfFirstOfMonth = date("w", strtotime($_GET['Year']."-".$_GET['Month']."-01"));
    $lastDayOfFirstWeek = 8 - $dayOfWeekOfFirstOfMonth;

    $weeksArray = array(array("firstDay"=>1, "lastDay"=>$lastDayOfFirstWeek));

    $loopDate = $lastDayOfFirstWeek + 1;

    while($loopDate < $endDate)
    {
        $weeksArray[] = array("firstDay"=>$loopDate, "lastDay"=>($loopDate+6 > $endDate ? $endDate : $loopDate+6));
        $loopDate+=7;
    }

    foreach($weeksArray as $week)
    {
        $dayStart = date("d.m.Y", strtotime($_GET['Year']."-".$_GET['Month']."-".$week["firstDay"]));
        $dayEnd = date("d.m.Y", strtotime($_GET['Year']."-".$_GET['Month']."-".$week["lastDay"]));

        echo $dayStart . "<br> to </br> " . $dayEnd . "</td>";

        //Rooms
        $sql2 = mysql_query("SELECT * FROM Rooms WHERE Status='T'", $mrrs);
        while ($rec2 = mysql_fetch_array($sql2)) {
            $RoomID = $rec2['Id'];
            $RoomName = $rec2['Room_Name'];
            $num=0;
            echo "<td align='center'>";

            //counting start
            $sql3 = mysql_query("SELECT * FROM Reservation WHERE (RoomID='".$RoomID."') AND (StartDate BETWEEN '".date("Y-m-d H:i:s", strtotime($dayStart))."' AND '".date("Y-m-d H:i:s", strtotime($dayEnd))."')",$mrrs);
            while ($rec3 = mysql_fetch_array($sql3)) {
                $num++;
            } echo $num;
            //counting end

            echo "</td>";
        } //Rooms
        echo "</tr><tr><td align='center'>";
    }
?>
    </td>

</tr>
</table>

Вот результат: Ссылка на выходное изображение

0

Я бы рекомендовал иметь таблицу календаря (по крайней мере, дату и неделю), поэтому, если предположить, что это существует как одна строка в таблице даты:

select
   c.weekno, room.id, min(c.dt) startweek_dt, max(c.dt) endweek_dt, count(r.bookingdate)
from calendar_table c
cross join room
left join reservation r on c.caldate = r.bookingdate and room.id = r.room_id
where c.dt >= '2017-01-01' and c.dt < '2017-02-01'
group by week(c.weekno), room.id

Здесь обсуждается создание таблицы календаря

0

Если вы говорите о том, почему весь год отображается, когда вы выбрали Jan, это может быть вызвано вашим выбором использования номера недели для получения диапазона дат.

Номер недели первого дня составляет 52 вместо 1. Это может вызвать проблемы. Существует много способов получить определенный диапазон дат. Вы могли бы попробовать другой способ сделать эту работу.

0

Вы можете использовать хранимую процедуру вместо запроса для динамического привязки даты.

CREATE PROCEDURE 'Reservation_data' (p_date1 date,p_date2 date)
BEGIN

SELECT concat(date_format(p_date1,'%d.%m.%Y'),' - ',date_format(p_date2,'%d.%m.%Y')), 
        sum(CASE WHEN room_id = 77 THEN 1 ELSE 0 END) AS Gold,
        sum(CASE WHEN room_id = 88 THEN 1 ELSE 0 END) AS Crystal,
        sum(CASE WHEN room_id = 99 THEN 1 ELSE 0 END) AS Dimond
FROM Reservations
WHERE BookingDate BETWEEN p_date1 AND p_date2
UNION 
SELECT concat(date_format(p_date1,'%d.%m.%Y'),' - ',date_format(p_date2,'%d.%m.%Y')), 
        sum(CASE WHEN room_id = 77 THEN 1 ELSE 0 END) AS Gold,
        sum(CASE WHEN room_id = 88 THEN 1 ELSE 0 END) AS Crystal,
        sum(CASE WHEN room_id = 99 THEN 1 ELSE 0 END) AS Dimond
FROM Reservations
WHERE BookingDate  BETWEEN p_date1 AND p_date2
UNION
SELECT concat(date_format(p_date1,'%d.%m.%Y'),' - ',date_format(p_date2,'%d.%m.%Y')), 
        sum(CASE WHEN room_id = 77 THEN 1 ELSE 0 END) AS Gold,
        sum(CASE WHEN room_id = 88 THEN 1 ELSE 0 END) AS Crystal,
        sum(CASE WHEN room_id = 99 THEN 1 ELSE 0 END) AS Dimond
FROM Reservations
WHERE BookingDate BETWEEN p_date1 AND p_date2
UNION
SELECT concat(date_format(p_date1,'%d.%m.%Y'),' - ',date_format(p_date2,'%d.%m.%Y')), 
        sum(CASE WHEN room_id = 77 THEN 1 ELSE 0 END) AS Gold,
        sum(CASE WHEN room_id = 88 THEN 1 ELSE 0 END) AS Crystal,
        sum(CASE WHEN room_id = 99 THEN 1 ELSE 0 END) AS Dimond
FROM Reservations
WHERE BookingDate BETWEEN p_date1 AND p_date2
UNION 
SELECT concat(date_format(p_date1,'%d.%m.%Y'),' - ',date_format(p_date2,'%d.%m.%Y')),  
        sum(CASE WHEN room_id = 77 THEN 1 ELSE 0 END) AS Gold,
        sum(CASE WHEN room_id = 88 THEN 1 ELSE 0 END) AS Crystal,
        sum(CASE WHEN room_id = 99 THEN 1 ELSE 0 END) AS Dimond
FROM Reservations
WHERE BookingDate BETWEEN p_date1 AND p_date2;

END$$
0

Ну, вы можете попробовать построить следующий запрос

 SELECT '1.12.2017 - 3.12.2017', 
        sum(CASE WHEN room_id = 77 THEN 1 ELSE 0 END) AS Gold,
        sum(CASE WHEN room_id = 88 THEN 1 ELSE 0 END) AS Crystal,
        sum(CASE WHEN room_id = 99 THEN 1 ELSE 0 END) AS Dimond,
FROM Reservations
WHERE BookingDate BETWEEN '2017-12-01 00:00:00' AND '2017-12-03 23:59:59'
UNION 
SELECT '4.12.2017 - 10.12.2017', 
        sum(CASE WHEN room_id = 77 THEN 1 ELSE 0 END) AS Gold,
        sum(CASE WHEN room_id = 88 THEN 1 ELSE 0 END) AS Crystal,
        sum(CASE WHEN room_id = 99 THEN 1 ELSE 0 END) AS Dimond,
FROM Reservations
WHERE BookingDate BETWEEN '2017-12-04 00:00:00' AND '2017-12-10 23:59:59'
UNION
SELECT '11.12.2017 - 17.12.2017', 
        sum(CASE WHEN room_id = 77 THEN 1 ELSE 0 END) AS Gold,
        sum(CASE WHEN room_id = 88 THEN 1 ELSE 0 END) AS Crystal,
        sum(CASE WHEN room_id = 99 THEN 1 ELSE 0 END) AS Dimond,
FROM Reservations
WHERE BookingDate BETWEEN '2017-12-11 00:00:00' AND '2017-12-17 23:59:59'
UNION
SELECT '18.12.2017 - 24.12.2017', 
        sum(CASE WHEN room_id = 77 THEN 1 ELSE 0 END) AS Gold,
        sum(CASE WHEN room_id = 88 THEN 1 ELSE 0 END) AS Crystal,
        sum(CASE WHEN room_id = 99 THEN 1 ELSE 0 END) AS Dimond,
FROM Reservations
WHERE BookingDate BETWEEN '2017-12-18 00:00:00' AND '2017-12-24 23:59:59'
UNION 
SELECT '25.12.2017 - 31.12.2017 ', 
        sum(CASE WHEN room_id = 77 THEN 1 ELSE 0 END) AS Gold,
        sum(CASE WHEN room_id = 88 THEN 1 ELSE 0 END) AS Crystal,
        sum(CASE WHEN room_id = 99 THEN 1 ELSE 0 END) AS Dimond,
FROM Reservations
WHERE BookingDate BETWEEN '2017-12-25 00:00:00' AND '2017-12-31 23:59:59'

Вам нужно создать такой запрос, используя нужные параметры для вывода. Таким образом, вы сможете получить результат одним выстрелом. Теперь проблема только в том, что RoomID и RoomName не выглядят динамичными. Но то же самое, что вам нужно будет создать в запросе динамически. Итак, если завтра появится другая комната, она также появится в запросе.

  • 0
    но мне нужно изменить диапазон дат тоже, динамически в зависимости от выбора. критерии WHERE должны соответствовать динамическому диапазону дат.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню