admin

Postgres日期重叠约束

sql

我有一个这样的表:

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)

编辑:我发现了一些东西:

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/

我唯一的问题是,它不能将空值用作结束时间戳记,我曾想将其替换为无限值,但效果不佳。


阅读 209

收藏
2021-05-10

共1个答案

admin

好吧,我最终这样做了:

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;

nb:如果您没有null时间戳,则无需使用时间扩展,可以使用我的问题中指定的box方法。

2021-05-10