如何计算日期范围内的记录及其标准

时间:2017-12-12 04:02:33

标签: php mysql count

我有两个数据库:

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's 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's 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']检索日期范围的月份和年份。日期范围应根据选定的月份和年份动态变化..
  • 日期范围是任何选定月份的星期范围,因此没有固定的星期范围。
  • 应从中检索表格标题上的房间名称 数据库表'房间'。
  • 计算应计算日期范围内特定房间的预订次数。

谢谢..

5 个答案:

答案 0 :(得分: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看起来不动态。但同样,您需要动态地在查询中构建它。因此,如果明天会增加另一个房间,它也会显示在查询中。

答案 1 :(得分:0)

我建议有一个日历表(至少是date和weekno),所以假设每个日期表存在一行:

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

这是discussion on building a calendar table

答案 2 :(得分: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$$

答案 3 :(得分:0)

如果您对选择Jan时显示全年的原因感到担忧,可能是因为您选择使用周数来获取日期范围。

一年中第一天的周数是52而不是1.这可能会导致问题。有很多方法可以获得特定的日期范围。您可以尝试其他方式来完成这项工作。

答案 4 :(得分: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>

这是输出: Link to the output image