【问题标题】:Checking for free slots in a booking system检查预订系统中的空闲时段
【发布时间】:2017-09-19 15:11:17
【问题描述】:

我正在寻求帮助,因为我正在尝试创建一个测试预订系统,但每个人都需要在特定时间被预订到特定的机器(笔记本电脑)上。请参阅以下数据库:

为糟糕的形象道歉,但希望你能明白这一点。我有数据库可以向我显示预订记录,但我希望能够查看剩下的内容。

我目前有 10 台机器,每台机器都有 3 个时隙,您可以像这样更容易地想象:

****************************************************************
* Machine/Laptop *   Time Slot   *      Name      *     Test   *
****************************************************************
*                * 09:30 - 11:00 * John Adams     * English    *
*    Laptop 1    * 11:00 - 13:00 * Book Slot      * Free       *
*                * 13:00 - 14:00 * Raj Patel      * English    *
****************************************************************
*                * 09:00 - 12:00 * Joe King       * English    *
*    Laptop 2    * 11:00 - 13:00 * Andrew Lil     * Maths      *
*                * 13:00 - 12:00 * Book Slot      * Free       *
****************************************************************

现在我不知道如何使单个数据库查询工作,但例如,这是一种非常肮脏的方法,每次加载页面时都会检查数据库 30 次:

$sql = $dbconn->prepare('SELECT COUNT(*) AS `total` 
                          FROM event_booking 
                          INNER JOIN event_machine
                          ON event_booking.machine_id=event_machine.id
                          INNER JOIN event_machine_time
                          ON event_booking.machine_time_id=event_machine_time.id
                          WHERE information_id = '.$_GET["id"].' AND event_machine.id=1 AND event_machine_time.id=2');
    $sql->execute();
    $result = $sql->fetchObject();
    if ($result->total > 0) { echo 'Slot Booked'; } else { echo '<a href="booking.php">Book Slot</a>'; }

每次调用它时,我都必须更改 event_machine.id=? AND event_machine_time.id=? 以调用特定插槽。

我确定我正在接近这个错误,所以任何帮助都会很棒:)

编辑:

如果有帮助,这就是我的目标

如您所见,紫色按钮是活动槽位,较暗的槽位已预订。对于演示,我只能安装 10 台笔记本电脑中的 5 台,但你明白了。

这是我用来调用所有活动预订的数据库查询。这显示了在活动中从event_information 进行的所有预订,然后我在表格中使用fetchAll。但我不知道是否可以使用此查询将预订 ID 转移到时间段?

$Event_list = $dbconn->prepare('SELECT
                                  event_booking.id,
                                  event_booking.live,
                                  event_booking.confirmation_email,
                                  event_candidate.firstname,
                                  event_candidate.surname,
                                  event_candidate.email,
                                  event_information.type,
                                  event_machine.id AS machine_get_id,
                                  event_machine.name,
                                  event_machine_time.id AS machine_time_get_id,
                                  event_machine_time.start_time AS machine_start_time,
                                  event_machine_time.end_time AS machine_end_time
                                  FROM event_booking
                                  INNER JOIN event_candidate
                                  ON event_booking.candidate_id=event_candidate.id
                                  INNER JOIN event_information
                                  ON event_booking.information_id=event_information.id
                                  INNER JOIN event_machine
                                  ON event_booking.machine_id=event_machine.id
                                  INNER JOIN event_machine_time
                                  ON event_booking.machine_time_id=event_machine_time.id
                                  WHERE information_id = ?'); 
    $Event_list->execute(array($_GET["id"]));

另一个编辑:

另一种选择是取消 event_machine 并将名为 machine_name 的列添加到 event_machine_time 中,然后使用以下内容:

$Event_Times = $dbconn->query('SELECT *
                                   FROM event_machine_time
                                   LEFT JOIN event_booking
                                   ON event_machine_time.id=event_booking.machine_time_id
                                   '); 

在表格中使用它:

<td>
        <?php foreach ($Event_Times->fetchAll() as $Event_Times_Row) { ?>
            <?php if($Event_Times_Row["machine_name"] == "Laptop 1") { ?>
            <a class="button<?php if($Event_Times_Row["information_id"] == $_GET["id"]) { echo " button-disabled"; } ?>" href="#"><?php echo date("G:i", strtotime($Event_Times_Row["start_time"])); ?></a>
        <?php } } ?>
</td>

但是我需要调用 10 次,我认为 fetchAll 不允许这样做,我需要重复此数据库查询 10 次才能使其工作。

【问题讨论】:

  • 不是您当前的问题,但您正在滥用准备好的语句。变量应该被绑定。 WHERE information_id = ? 然后$sql-&gt;execute(array($_GET["id"]));
  • 抱歉,我举了这个例子,但你在我所有的现场项目中都是正确的
  • 单独存储event_machine_time有什么好处?
  • 没什么,这只是我的方法,否则机器和时间可能在同一个表中,这意味着我将有三行,每行具有相同的机器名称。我想它对扩展时间和机器很有用,但我可以改变它。
  • stackoverflow.com/questions/43167887/… 这就是你想要的,不是吗?

标签: php mysql pdo


【解决方案1】:

您的方法需要一些更正:

  1. event_machine_time 表必须与event_machine 表相关。所以event_machine_time表必须有一个字段名event_machine_id

  2. 之后,您不需要event_bookingevent_machine 表之间的直接关系,因为它可以从上一步中的其他关系中发现。

  3. 最好从event_information 表中删除start_date& end_date 字段,因为它们是相等的。您必须插入一个新的 event_date 代表它们。

  4. 您必须从event_information 表中删除start_timeend_time 字段,因为它们可以从与主表相关的event_machine_time 表中发现以保持数据集成。

  5. 最好将event_information 表包含在主booking_event 表中,因为这些表之间存在一对一的关系。

进行这些更改后,您想要做的一切都会变得非常简单。

【讨论】:

    【解决方案2】:

    感谢大家的帮助,但这是我得出的结论:

    我通过删除event_machine 表修改了我的数据库,如下所示:

    event_booking 表中,我添加了一个名为machine_name 的列,并使用相同的笔记本电脑名称创建了三个条目,但时间不同,例如

    ****************************************
    * machine_name * start_time * end_time *
    ****************************************
    * Laptop 1     * 09:30      * 11:00    *
    * Laptop 1     * 11:30      * 13:00    *
    * Laptop 1     * 13:30      * 15:00    *
    * Laptop 2     * 09:30      * 11:00    *
    * Laptop 2     * 11:30      * 13:00    *
    * Laptop 2     * 13:30      * 15:00    *
    ****************************************
    

    使用它,我随后使用了以下数据库关系,我将其作为fetchAll() 循环运行:

    $Event_Times = $dbconn->query('SELECT *
                                       FROM event_machine_time
                                       LEFT JOIN event_booking
                                       ON event_machine_time.id=event_booking.machine_time_id
                                       ORDER BY start_time
                                       ');
    $Event_Times_Loop = $Event_Times->fetchAll(PDO::FETCH_ASSOC);
    

    然后我在一个 HTML 表格中运行了 10 次循环(照片中显示了 7 次):

    <td>
        <?php foreach ($Event_Times_Loop as $Event_Times_Row) { ?>
        <?php if($Event_Times_Row["machine_name"] == "Laptop 1") { ?>
        <a class="button<?php if($Event_Times_Row["information_id"] == $_GET["id"]) { echo " button-disabled"; } ?>" href="#"><?php echo date("G:i", strtotime($Event_Times_Row["start_time"])); ?></a>
        <?php } } ?>
    </td>   
    

    因此,使用一些 CSS 来禁用某人已经预订的按钮似乎工作得很好。很可能有一个更好、更清洁的解决方案,但至少我有一些可行的方法。也为我的术语道歉,我确定我也弄错了:)

    感谢您的帮助!

    【讨论】:

    • 您关于machine_name 的解决方案存在规范化问题。
    • 好的,它有效。但它有正常化问题。这意味着您无法获得例如机器的报告(没有时间)。
    • 对不起我真的不明白,是因为我对问题的理解
    • 阅读我的答案的第一步和第二步。
    • 但是第 1 步不再适用,因为我已将 event_machine_timeevent_machine 合并在一起
    猜你喜欢
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 2020-10-17
    • 2020-09-21
    • 1970-01-01
    相关资源
    最近更新 更多