18

My table has two columns:

  1. startsAt
  2. endsAt

Both hold date and time. I want to make following constraint:

IF both columns are NOT NULL then range between startsAt and endsAt must not overlap with other ranges (from other rows).

4
  • dba.stackexchange.com/questions/75034/… Commented Nov 4, 2014 at 13:11
  • I can't use range column - I have to operate on two columns: startsAt and endsAt. Commented Nov 4, 2014 at 13:22
  • Create a new column with datatype tsrange that takes startsAt and endsAt as input. A constraint on this new column fixes your problem. Commented Nov 4, 2014 at 13:26
  • 2
    You best edit the additional requirement into the question. Commented Nov 4, 2014 at 20:27

1 Answer 1

32

You can keep your separate timestamp columns and still use an exclusion constraint on an expression:

CREATE TABLE tbl ( tbl_id serial PRIMARY KEY , starts_at timestamp , ends_at timestamp , EXCLUDE USING gist (tsrange(starts_at, ends_at) WITH &&) -- no overlap ); 

Constructing a tsrange value without explicit bounds as tsrange(starts_at, ends_at) assumes default bounds: inclusive lower and exclusive upper - '[)', which is typically best.

db<>fiddle here
Old sqlfiddle

Related:

Add constraint to existing table

ALTER TABLE tbl ADD CONSTRAINT tbl_no_overlapping_time_ranges EXCLUDE USING gist (tsrange(starts_at, ends_at) WITH &&) 

Syntax details are the same as for CREATE TABLE.

Sign up to request clarification or add additional context in comments.

2 Comments

Could you describe how one could have the constraint tied to another column say 'client_id'?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.