我有一张这样的桌子:

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/

我唯一的问题是,它不能用空值作为结束时间戳,我曾想过用无穷大的值来替换它,但也不起作用.

推荐答案

好吧,我最后做了这个:

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.1CREATE EXTENSION btree_gist;中的扩展提供

注意:如果没有空时间戳,就不需要使用时间扩展,可以使用我的问题中指定的box方法.

Postgresql相关问答推荐

转换失败:(—122.763091,49.04676)转换为地理(位置)""

正在应用序列化迁移,但数据库没有更改

sqlalchemy在Flask 下运行时出现无法解释的错误

如何创建一个触发器来传播对主键表的更新?

气流数据库如何定期管理?

使用 select 在带有特殊字符的字符串中查找数据

如何为基于复合类型的 Postgres DOMAIN 定义 CHECK 约束

如何在 Sequelize ORM 中插入 PostGIS GEOMETRY 点?

postgresql中的外键可以被触发器违反

如何使用 ActiveRecord json 字段类型

错误:syntax error at or near "user"

在 PostgreSQL 中将时间转换为秒

为什么 PostgreSQL 将用户和组合并为角色?

在 PL/pgSQL 中声明行类型变量

没有查询要创建的in ... error

在 Windows 10 中执行时,Docker 容器关闭并给出data directory has wrong ownership错误

没有函数匹配给定的名称和参数类型

如何在 postgresql 中获取整个表的哈希?

PL/pgSQL 中的 BREAK 语句

如何从我的 postgresql 查询中获取最小值、中值和最大值?