我想在postgresql表列中保留预订日期

jvidinwx  于 2023-02-04  发布在  PostgreSQL
关注(0)|答案(1)|浏览(132)

我有一个名为villas的表,该表有一个名为reserved_dates的列,其类型为reserved_dates,位于daterange []中
我想在reserved_dates列中保留预订日期。别墅在特定日期之间预订。例如:入住日期:2023年2月5日退房日期:2023 - 02 - 15。在这种情况下,我可以手动将{"[2023-02-05,2023-02-15)"}值添加到reserved_dates列。
我想要的是例如当客户选择日期时

  • 入住日期:2023-02-10
  • 退房日期:2023-02-20

我想检查一下,所选的日期范围是否与数据库中的日期范围冲突?
如果没有预订日期,我想添加,我怎么做呢?或者我该怎么做呢?
在很多博客平台上,包括PostgreSQL 14文档,我都找不到想要的结果和新日期类型的使用。
我可以手动将日期范围添加到reserved_dates中,但如果预订重叠,则无法更新预订日期

lndjwyie

lndjwyie1#

排除约束可以满足您的需求,您需要包含的不仅仅是日期范围(一个房间在任何一天都不能被预订超过一次,但是同一天可以预订两个房间)。

CREATE EXTENSION IF NOT EXISTS BTREE_GIST;
CREATE TABLE demo_table(
    RoomNumber INTEGER NOT NULL,
    CheckIn  DATE NOT NULL,
    CheckOut DATE  NOT NULL,
    CHECK (CheckIn  < CheckOut ),
    EXCLUDE USING gist (RoomNumber WITH =, daterange(CheckIn, CheckOut, '[)'::text) WITH &&)
);

&&操作符是范围重叠(range1 && range2),您也可以在常规SELECT查询中测试它。
编辑:我看过你的评论。
第一点:细节决定成败。您将表命名为villas(复数),这意味着要管理的别墅不止一个。在这种情况下,应该有一个额外的列来标识哪个别墅链接到预订(如果不是RoomNumber INTEGER,则命名为VillaName TEXT)。
老实说,即使你只有一个别墅,它不会伤害规划未来,使它在未来添加另一个不需要你改变你的整个模式。
第2点:我不知道为什么要将保留存储在数组中,这可能是一个糟糕的设计选择(例如,它不允许您使用索引,也不允许轻松删除过去的记录)。
UNNEST是一个快速的解决方法,它将数组元素转换为记录。
示例:

SELECT *
FROM (
    SELECT UNNEST(reserved_dates) AS Reserved, [add other columns here]
    FROM villas
) R

但正确的做事方式,有人在评论中说,宁愿是这样的台词:

CREATE TABLE villaReservation ([...]);
INSERT INTO villaReservation SELECT UNNEST(reserved_dates), ... FROM villas
WHERE Reserved && daterange('2023-03-10', '2023-02-20', '[)'::text)

最后一件事:我个人更喜欢在表格中保持两个范围的界限分开(上面,保持分开的入住和退房日期)。
1.它使得从PostgreSQL迁移到另一个DBMS变得更加容易(表的CREATE脚本将不需要调整)。
1.它可能不适用于您的情况,但它可以使范围的形式为[date1, date1),即空范围,但在时间上的位置。
我实际上遇到了一个需要以这种方式保存内容的用例,尽管与您的上下文不同。

相关问题