【问题标题】:Find available time slots for table reservation system查找餐桌预订系统的可用时间段
【发布时间】:2020-09-21 08:38:36
【问题描述】:

我正在为餐桌预订系统创建一个数据库。每个表都有自己的时隙列表,我想为每个表找到 可用 时隙。 所以我有以下表格:

time_slots table
----------------------------------
id || table_id || weekday ||  time
==================================
 1           1          1    12:00
 2           1          1    12:30
...
11           1          1    16:00
...
17           1          1    19:00
18           1          1    19:30
...
27           1          1    00:00
==================================

reservations table
-----------------------------------------------------------------
id || table_slot_id ||          start_date ||            end_date
=================================================================
 1                1    2020-06-01 12:00:00    2020-06-01 12:20:00
 2                1    2020-06-01 16:00:00    2020-06-01 19:00:00
=================================================================

我写了一个查询,可以找到所有预留时间槽:

SELECT *
FROM table_slots, (SELECT * 
                   FROM reservations 
                   WHERE reservations.start_date::date = '2020-06-01'::date) as res
WHERE table_slots.weekday = extract(dow from '2020-06-01'::date)
AND table_slots.time BETWEEN res.start_date::time and res.end_date::time
ORDER BY table_slots.time

但我不明白如何编写查询来查找可用的时间段。所以我希望结果应该包含时间在 12:30 到 15:30 之间的所有 time_slots; 19:30 和 00:00。这个怎么做? 是否可以以最小的开销编写这样的查询? 最后一个问题,对于这样的系统来说,这是一个好的设计吗?如果不是,那么这些场景中更好的设计是什么。 谢谢!

【问题讨论】:

    标签: sql database postgresql date join


    【解决方案1】:

    您可以使用not exists。这将为您提供 6 月 1 日的所有可用时段:

    select ts.*
    from time_slots ts
    where not exists (
        select 1
        from reservations r
        where 
            r.table_slot_id = ts.id
            and r.start_date >= '2020-06-01'::date
            and r.start_date <  '2020-07-01'::date
            and r.start_date::time <= ts.time
            and r.end_date::time   >  ts.time 
    )
    

    请注意,这是假设预订不跨越天数。

    将子查询的where 子句表示为:

        where 
            r.table_slot_id = ts.id
            and r.start_date >= '2020-06-01'::date
            and r.start_date <= '2020-06-01'::date + ts.time::interval
            and r.end_date   >  '2020-06-01'::date + ts.time::interval 
    

    这将利用reservations(table_slot_id, start_date, end_date) 上的索引。

    【讨论】:

    • 但是查询结果包括除12:00以外的所有时间段
    猜你喜欢
    • 2018-03-28
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 2017-09-19
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多