【问题标题】:Logic when checking availability of slot bookings in SQL在 SQL 中检查插槽预订可用性时的逻辑
【发布时间】:2017-10-20 00:25:28
【问题描述】:

我有一个简单的测试系统,它有固定的时间段与笔记本电脑相连,用于培训日,称为event_machine_time

*************************************************
id   * machine_laptop * machine_name * start_time
*************************************************
1    * Lenovo 001     * XXX45435     * 09:00
2    * Lenovo 001     * XXX45435     * 11:00
3    * Lenovo 002     * YER45435     * 09:00
4    * Lenovo 002     * YER45435     * 11:00
*************************************************

我有另一个表格,用于收集有关预订详细信息的信息,名为 event_booking

**************************************************************
id * information_id *   machine_time_id * firstname * surname
**************************************************************
1  * 1              *  1                * Joe       * Blogs
2  * 1              *  3                * Jane      * Smith
**************************************************************

上面的表格与另一个保存事件信息的表格event_information联系在一起

*****************************************
id * date       *  name
*****************************************
1  * 08-21-2017 *  Testing Day
2  * 08-21-2017 *  Testing Day Follow-Up           
*****************************************

所以根据以上信息,我知道已经进行了以下预订:

Testing day on 21st August 2017
Joe Blogs - XXX45435 - 09:00
Jane Smith - YER45435 - 09:00

所以我知道我可以通过加入这两个表来查看所有预订

SELECT
event_machine_time.id AS machine_id,
event_booking.id AS booking_id,
event_machine_time.start_time,
event_machine_time.machine_laptop,
FROM event_machine_time
LEFT JOIN event_booking
ON event_machine_time.id=event_booking.machine_time_id
WHERE information_id= :id
ORDER BY machine_name ASC, start_time ASC

但是,我想创建一个仅显示可用时间的选择框。我可以使用 JS 来过滤机器,但我想一直显示但禁用任何已经预订的插槽。这就是我卡住的地方。

输出槽超级简单:

...choose the machine via a select box and call the Ajax request...

$machine_id = $_POST['machine'];

$Get_Testing_Slots_Query = "
SELECT *
    FROM event_booking
    WHERE machine_time_id = :t_id";

$Get_Testing_Slots = $dbconn->prepare($Get_Testing_Slots_Query);
    $Get_Testing_Slots->bindParam(":t_id",$machine_id);
    $Get_Testing_Slots->execute();

...output all the testing slots...

我知道我可以使用 foreach 加载所有插槽,然后运行 ​​function 检查插槽是否空闲,但这似乎是一种非常复杂的方法。

有没有办法可以输出所有的 start_times 并将其链接回 machine_time_id 以便我知道有预订?

所以基本上我希望选择框显示以下内容:

************
* XXX45435 * (selected above)
************

***************
*9:00am BOOKED*
*11:00am FREE *
***************

编辑:

抱歉,我错过了一个关键部分!保存名为event_information 的事件信息的附加表。我已经进行了上述更改。

【问题讨论】:

  • 您使用 LEFT JOIN 的查询是否已经完成了您想要做的事情?如果booking_id 为空,则该插槽是开放的,否则它已被预订。
  • 所以除非我做错了LEFT JOIN 输出任何匹配的东西,它不会输出空值。所以它显示 event_machine_time id 1 & 3 但不是 2 & 4
  • @JosephGregory A LEFT JOIN 是左外连接,这意味着它将返回“左侧表”(在本例中为 event_machine_time)中的所有行,并尝试查找匹配右侧表格中的行。如果没有匹配的行,则返回左表中指定的列,并为右表中的列返回 null。您所描述的是内部连接。
  • 试试这个SELECT * FROM event_information A inner join event_machine_time B on (1=1) left join event_booking C on (B.id = C.machine_time_id and A.id = C.information_id ) WHERE A.id = '1'
  • 它是event_machine_timeevent_information 之间的笛卡尔积,因为每台计算机在每个事件的所有时段都可用。然后它会检查机器是否在那个时间、日期和时间段被预订。

标签: php sql


【解决方案1】:

试试这个。

SELECT * 
FROM event_information A
inner join event_machine_time B on (1=1) 
left join event_booking C on (B.id = C.machine_time_id and A.id = C.information_id ) 
WHERE A.id = '1'

它是 event_machine_time 和 event_information 之间的笛卡尔积,因为每台计算机在每个事件的所有时段都可用。然后它会检查机器是否在那个时间、日期和时间段被预订。

【讨论】:

    【解决方案2】:

    您已经在查询中使用了左连接,并从event_booking 中选择了一列,所以您快到了!

    如果event_machine_time 中的特定时间段没有任何预订,SQL 语句将为booking_id 返回一个空值。尝试在你的循环中添加这样的东西,在你的选择框中输出每一行:

    print $row['start_time'];
    
    if (is_null($row['booking_id']))
    {
        print ' FREE';
    }
    else
    {
        print ' BOOKED';
    }
    

    【讨论】:

    • 您应该测试$row['booking_id'] === null 还是is_null($row['booking_id']) 而不是将其与空字符串进行比较?
    • @bassxzero 你是对的,它应该检查空值,而不是空值。
    • 抱歉我错过了一个我现在已经纠正的链接表!
    • @JosephGregory 新表是否会改变此逻辑的工作方式?您的问题仍然表明您希望在选择框中具有相同的输出。我还看到您对问题的评论表明左连接和内连接可能存在一些混淆。
    猜你喜欢
    • 1970-01-01
    • 2021-10-13
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多