This seems to be a misunderstanding.
Your quote from my answer is a bit misleading, since it only applies if you also create the additional partial index as described over there:
How to add a conditional unique index on PostgreSQL
If you do not add this second index (like you did not), you already have your solution, it would seem. With the multicolumn unique index alone, you can enter (1, NULL)
multiple times, but (1,2)
or (1,3)
only once.
Empty strings
If, by mistake, you were considering empty strings (''
) (for a character type) instead of NULL
values: those are handled like any other value. You could deal with this situation using a multicolumn, partly functional unique index (index on an expression):
CREATE UNIQUE INDEX predictions _dim_tat_uni_idx
ON predictions (tat, NULLIF(dim, ''));
This way you can enter (1, 'a')
, (1, 'b')
only once.
But (1, NULL)
and (1, '')
multiple times.
Side effects
The index would still fully support plain queries on the first column (tat
).
But queries on both columns would have to match the expression to utilize the full potential. This would be faster, even if it doesn't seem to make sense:
SELECT * FROM predictions
WHERE tat = 1
AND NULLIF(dim, '') = 'foo';
.. than this:
SELECT * FROM predictions
WHERE tat = 1
AND dim = 'foo';
.. because the first query can use both index columns. Result would be the same (except when searching for ''
or NULL
). Details in this related answer on dba.SE.