SQL:列为特定值时的唯一约束

SQL:列为特定值时的唯一约束,sql,postgresql,Sql,Postgresql,当只有特定条件存在时,试图想出正确的语法来创建唯一的约束时,大脑会变得迟钝 给定,type可以有值A-F,每个日期只能有一个A,但可以有多个B-F。良好表格示例: CREATE TABLE foo ( dt AS DATE NOT NULL, type AS TEXT NOT NULL, CONSTRAINT unique_dt_type UNIQUE(dt,type) -- check constraint(?) ) 尝试阅读check/unique语法,但没有

当只有特定条件存在时,试图想出正确的语法来创建唯一的约束时,大脑会变得迟钝

给定,
type
可以有值
A-F
,每个日期只能有一个
A
,但可以有多个
B-F
。良好表格示例:

CREATE TABLE foo (
   dt     AS DATE NOT NULL,
   type   AS TEXT NOT NULL,
   CONSTRAINT unique_dt_type UNIQUE(dt,type) -- check constraint(?)
)

尝试阅读check/unique语法,但没有任何示例<代码>检查非常接近,但仅将其限制在一个范围内,并且没有与
独特的
场景结合使用。也尝试了搜索,但是我的搜索技巧不是很好,或者没有类似的问题。

< P> > PostgreSQL可以通过它的“部分索引”特征来满足你的需求。实际上,这是通过在CREATEINDEX语句中添加where子句来实现的

样本:

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'
请看这里:

特别注意
示例11-3一节。设置部分唯一索引
。它给出了一个与你所陈述的目标相符的例子

CREATE INDEX my_partial_ix ON my_sample_table (my_sample_field)
WHERE (my_sample_field = 'rows to index');
使用触发器:

CREATE UNIQUE INDEX my_partial_ix ON my_sample_table (my_sample_field)
WHERE NOT (my_sample_field = 'duplicates ok');

你可以轻松地使用触发器@听起来很有希望,你有一个简单的例子吗?当我搜索
sql conditional unique
时,我确实找到了一些结果,但没有成功(它们被注明日期),我可能已经找到了此处所述问题的解决方案:,如果
在索引创建过程中允许
,请在Postgres手册中查找“部分索引”。您可以执行
创建唯一索引。。。其中…
,它将像约束一样强制执行。(我在打电话,否则我会把它扩展成一个答案)哈,我们都在几秒钟之内得到了相同的答案。我发帖的时候它不在那里,太复杂了。这不会扩展,使用部分索引会更快、更健壮。此外,索引会自动加快匹配查询的速度。只有一个小缺点:索引需要一些磁盘空间。
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;