Postgres - 基于另一列在列中设置唯一约束

Nat*_*izz 5 sql postgresql database-design unique-constraint sql-insert

我有一个这样的表:

\n\n
CREATE TABLE schema.mytable\n(\n  id serial NOT NULL,\n  number integer NOT NULL,\n  state boolean NOT NULL,\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n

我需要创建一组唯一的 \xc2\xb4number\xc2\xb4 但是,状态列必须为 true;如果状态列为假,则数字可以重复,这是我需要有效的示例:

\n\n
id  number      state\n1   123         true\n2   124         true\n3   125         true\n4   123         false\n5   129         false\n
Run Code Online (Sandbox Code Playgroud)\n\n

如您所见,数字 123 被重复,但在一种情况下状态为 false,另一种情况为 true;这是不正确的:

\n\n
id  number      state\n1   123         true\n2   124         true\n3   125         true\n4   123         true (*incorrect)\n5   129         false\n
Run Code Online (Sandbox Code Playgroud)\n\n

另外,123也有可能以错误状态重复两次或更多次;我怎样才能实现这个目标?

\n

GMB*_*GMB 4

您不能有部分唯一约束,但您可以创建部分唯一索引,它实现完全相同的功能:

create unique index mytable_bk on mytable(number) where (state);
Run Code Online (Sandbox Code Playgroud)

DB Fiddle 上的演示

insert into mytable(id, number, state) values(1, 123, false);
-- 1 rows affected

insert into mytable(id, number, state) values(1, 123, true);
-- 1 rows affected

insert into mytable(id, number, state) values(1, 123, false);
-- 1 rows affected

insert into mytable(id, number, state) values(1, 123, true);
-- ERROR:  duplicate key value violates unique constraint "mytable_bk"
-- DETAIL:  Key (number)=(123) already exists.
Run Code Online (Sandbox Code Playgroud)