CREATE TABLE foo (
dt AS DATE NOT NULL,
type AS TEXT NOT NULL,
CONSTRAINT unique_dt_type UNIQUE(dt,type) -- check constraint(?)
)
当只有特定条件存在时,在尝试考虑正确的语法来创建唯一约束时,有一个大脑 -
鉴于,type
可以包含值A-F
,每个日期只能有一个A
,但可以有多个B-F
。好桌子的例子:
2010-01-02 | 'A' -- only one
2010-01-02 | 'B' -- can have multiple
2010-01-02 | 'B'
2010-01-02 | 'B'
2010-01-02 | 'C' -- can have multiple
2013-01-02 | 'A' -- only one
2010-01-02 | 'B' -- can have multiple
2010-01-02 | 'B'
2013-01-02 | 'F' -- can have multiple
2013-01-02 | 'F'
尝试阅读检查/唯一语法,但没有任何示例。 CHECK
接近但仅限于某个范围,并未与UNIQUE
方案一起使用。也试过搜索,但我的搜索技巧要么不高,要么没有类似的问题。
答案 0 :(得分:24)
PostgreSQL可以通过它的“部分索引”功能满足您的需求。实际上,这是通过在create index语句中添加where子句来实现的。
示例:
CREATE INDEX my_partial_ix ON my_sample_table (my_sample_field)
WHERE NOT (my_sample_field = 'duplicates ok');
看看这里: http://www.postgresql.org/docs/current/interactive/indexes-partial.html
特别注意Example 11-3. Setting up a Partial Unique Index
部分。它给出了一个与您声明的目标很好地对齐的例子。
答案 1 :(得分:1)
使用触发器:
CREATE OR REPLACE FUNCTION "CheckConstraint"()
RETURNS trigger AS
$BODY$declare
already_exists boolean;
begin
if new.foo_type='A' then
select count(*) >0 from foo where foo_type='A' and dt=new.dt INTO already_exists;
if already_exists then
raise exception 'date % already have an A', new.dt;
end if;
end if;
return new;
end;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;