2017-01-30 27 views
1

我有一个保留表。预约包括日期范围和时间范围。他们也属于其他几个模型。我想添加一个约束条件,使得保留不可能发生重叠时间。如何在PostgreSQL中为where子句添加约束?

我有这样的:

CREATE TABLE reservations (
    id integer NOT NULL,  
    dates daterange, 
    times timerange, 
    desk_id integer NOT NULL, 
    space_id integer, 
); 

ALTER TABLE reservations ADD EXCLUDE USING gist (dates WITH &&, times WITH &&) 

它运作良好。但是我希望这个约束被限制在desk_id和client_id范围内。

当此记录与desk_id或space_id不同时,应该可以保存重叠时间/日期的记录。

我该怎么做?

回答

2

您可以使用与您使用的完全相同的机制,但也会将desk_idspace_id添加到您的排除项目中。这一次,而不是使用&&运营商(意为重叠)与=操作:

ALTER TABLE reservations 
    ADD EXCLUDE 
    USING gist (desk_id WITH =, space_id WITH =, dates WITH &&, times WITH &&) ; 

论文插入会的工作,因为它们涉及两种不同的desk_id

INSERT INTO 
    reservations 
    (id, dates, times, desk_id, space_id) 
VALUES 
    (1, '[20170101,20170101]'::daterange, '[10:00,11:00]'::timerange, 10, 10), 
    (2, '[20170101,20170101]'::daterange, '[10:30,11:00]'::timerange, 20, 10) ; 

该插入会失败,因为你会有一个时间范围重叠,并且相同desk_idspace_id

INSERT INTO 
    reservations 
    (id, dates, times, desk_id, space_id) 
VALUES 
    (3, '[20170101,20170101]'::daterange, '[10:00,11:00]'::timerange, 10, 10) ; 
+0

优秀, 谢谢。我必须先做一个'CREATE EXTENSION btree_gist;'。 使用两个不同字段来表示日期和时间的原因是,预订是在某个日期范围内的特定时段。认为“周一到周五从9:00到15:00”。 如果我只有一个'datetimes tsrange',那么这个时间范围将是一个连续统。 – Nerian

+0

好吧,明白了,是有道理的。你有限制,你不能越过00:00边界。我清除了不适用的部分答案。 – joanolo