我有这样一张桌子:
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
Run Code Online (Sandbox Code Playgroud)
我想禁止给定的重叠间隔 (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 &&
)
);
Run Code Online (Sandbox Code Playgroud)
如果您想了解更多有关此内容的信息,请访问http://www.depesz.com/2010/01/03/waiting-for-8-5-exclusion-constraints/
我唯一的问题是它不能使用空值作为结束时间戳,我想用无限值替换它但不起作用.
yok*_*oko 26
好的,我最终做到了这一点:
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 &&
)
);
Run Code Online (Sandbox Code Playgroud)
与无限,交易证明完美配合.
我只需安装时间扩展,这将在postgres 9.2中生成,btree_gist可作为9.1中的扩展. CREATE EXTENSION btree_gist;
nb:如果你没有空时间戳,就不需要使用时间扩展,你可以使用我的问题中指定的box方法.
在最新的 postgres 版本中(我在 9.6 中对其进行了测试,但我认为它可以在 >=9.2 中工作)您可以使用tstzrange()
其他一些评论中提到的内置函数。默认情况下,空值将被视为正无穷大或负无穷大,然后不再明确需要 CHECK 约束(如果您认为检查只是<=
一个范围可以以相同日期开始和结束)。只btree_gist
需要扩展名:
CREATE EXTENSION btree_gist;
CREATE TABLE test (
from_ts TIMESTAMPTZ,
to_ts TIMESTAMPTZ,
account_id INTEGER DEFAULT 1,
product_id INTEGER DEFAULT 1,
CONSTRAINT overlapping_times EXCLUDE USING GIST (
account_id WITH =,
product_id WITH =,
TSTZRANGE(from_ts, to_ts) WITH &&
)
);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7864 次 |
最近记录: |