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'?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.