Is it possible to have a custom unique column constraint as follows? Suppose I have two cols, subset and type, both strings (though the data types probably doesn't matter).

If type is "true", then I want the combination of type and subset to be unique. Otherwise, there is no constraint. I'm using PostgreSQL 8.4 on Debian.


In other words, you want subset to be unique if type = 'true'.
A partial unique index will do that:

CREATE UNIQUE INDEX tbl_some_name_idx ON tbl (subset) WHERE type = 'true';

This way you can even make combinations with NULL unique, which is not possible otherwise - as detailed in this related answer:
PostgreSQL multi-column unique constraint and NULL values


This is supplemental to Erwin's answer above, but PostgreSQL supports a bunch of types of indexes. These are not generally mutually exclusive. You can think of these as being:

  • Index method (btree, GiST, GIN, etc). Choose one, if necessary (btree being the default)
  • Partial or full. If partial use a where clause
  • Direct or functional. You can index the output of functions.
  • Unique or non-unique

These can all be combined in various ways. All you are doing here is using the unique and partial features, so that gives you partial unique indexes (which are extremely useful as you are finding out.

But suppose you want to have a case insensitive index on the subset field where type is true. Then you would add a functional definition:

CREATE INDEX my_index_name_idx_u ON tbl (lower(subset)) WHERE type;

Note this creates a unique index on the output of the lower() function called on the subset attribute where type is true.

  • So the index in Erwin's answer is direct, whereas the one in your example in functional, correct? – Faheem Mitha Mar 24 '13 at 18:12
  • @FaheemMitha: Correct. – Erwin Brandstetter Mar 24 '13 at 21:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.