I currently have the following constraint on a table:
ALTER TABLE myTable
ADD CONSTRAINT unique_row UNIQUE (content_id, brand_id, language_id);
I want to add a condition to the constraint: I want the constraint to work the same way, but with only a single row where is_archived is FALSE:
ALTER TABLE myTable
ADD CONSTRAINT unique_row UNIQUE (content_id, brand_id, language_id, !is_archived);
However, when I do this I get a syntax error.
If is_archived = true
then multiple rows with the same combination of content_id
and brand_id
are allowed. Basically multiple rows that are the same can be archived, but only one can be unarchived.
-
A partial index is likely the most efficient solution, but you may also be interested in: dba.stackexchange.com/questions/276505/…Lennart - Slava Ukraini– Lennart - Slava Ukraini2020年12月06日 12:20:54 +00:00Commented Dec 6, 2020 at 12:20
1 Answer 1
While Postgres doesn't allow a partially unique constraint, it does support a partial unique index:
create unique index unique_row on myTable(content_id, brand_id) where not is_archived;
See Partial Indexes in the Postgres documentation.
This is effectively pretty much the same as a unique constraint, because such constraints are implemented with unique indexes anyway.
-
Index lacks an option to be mentioned in ON CONFLICT case where only unique keys are accepted.Alex Dvoretsky– Alex Dvoretsky2022年05月19日 18:54:30 +00:00Commented May 19, 2022 at 18:54
-
3@AlexDvoretsky You can! You have to specify the same
where
that the partial index has after the columns in theon conflict
clause. eg... on conflict(content_id, brand_id) where not is_archived do update ...
Colin 't Hart– Colin 't Hart2022年05月19日 18:59:30 +00:00Commented May 19, 2022 at 18:59