我有一个这样的表:
date_start date_end account_id product_id 2001-01-01 2001-01-31 1 1 2001-02-01 2001-02-20 1 1 2001-04-01 2001-05-20 1 1
我想禁止给定的重叠间隔 (account_id, product_id)
(account_id, product_id)
编辑:我发现了一些东西:
CREATE TABLE test ( from_ts TIMESTAMPTZ, to_ts TIMESTAMPTZ, account_id INTEGER, product_id INTEGER, CHECK ( from_ts < to_ts ), CONSTRAINT overlapping_times EXCLUDE USING GIST ( account_id WITH =, product_id WITH =, box( point( extract(epoch FROM from_ts at time zone 'UTC'), extract(epoch FROM from_ts at time zone 'UTC') ), point( extract(epoch FROM to_ts at time zone 'UTC') , extract(epoch FROM to_ts at time zone 'UTC') ) ) WITH && ) );
如果您想了解更多有关此信息,请访问http://www.depesz.com/2010/01/03/waiting-for-8-5-exclusion- constraints/
我唯一的问题是,它不能将空值用作结束时间戳记,我曾想将其替换为无限值,但效果不佳。
好吧,我最终这样做了:
CREATE TABLE test ( from_ts TIMESTAMPTZ, to_ts TIMESTAMPTZ, account_id INTEGER DEFAULT 1, product_id INTEGER DEFAULT 1, CHECK ( from_ts < to_ts ), CONSTRAINT overlapping_times EXCLUDE USING GIST ( account_id WITH =, product_id WITH =, period(from_ts, CASE WHEN to_ts IS NULL THEN 'infinity' ELSE to_ts END) WITH && ) );
与无限,交易证明完美配合。
我只需要安装时间扩展,它将在postgres 9.2中是本地的,而btree_gist在9.1中可以作为扩展 CREATE EXTENSION btree_gist;
CREATE EXTENSION btree_gist;
nb:如果您没有null时间戳,则无需使用时间扩展,可以使用我的问题中指定的box方法。