Postgres唯一日期时间范围约束

18

我的表有两列:

  1. startsAt
  2. endsAt

两者都保存日期和时间。 我想要设置以下约束:

如果这两列都不为空,则 startsAt 和 endsAt 之间的范围不能与其他行的范围重叠。


http://dba.stackexchange.com/questions/75034/unique-constraint-to-enforce-max-one-null-per-item/75036#75036 - user330315
我无法使用 range 列 - 我必须操作两个列:startsAtendsAt - user606521
创建一个新列,数据类型为tsrange,以startsAt和endsAt作为输入。对这个新列的约束可以解决你的问题。 - Frank Heikens
2
你最好将额外的要求编辑到问题中。 - Erwin Brandstetter
1个回答

29
你可以保留自己的单独的timestamp列,并仍然在表达式上使用排除约束
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
);
使用默认边界(包含下限和不包含上限的“[)”)构建一个没有显式边界的tsrange值通常是最好的选择:Constructing a tsrange value without explicit bounds as tsrange(starts_at, ends_at) assumes default bounds: inclusive lower and exclusive upper - '[)'

db<>fiddle 在这里
旧版sqlfiddle

相关:

向现有表添加约束

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

语法细节与CREATE TABLE相同。


1
你能描述一下如何将约束与另一列(比如“client_id”)绑定吗? - Daniel Nicoletti
2
@DanielNicoletti:是的。请参见https://stackoverflow.com/a/20513792/939860或https://stackoverflow.com/a/27348912/939860。 - Erwin Brandstetter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接