1

How to add a unique index on text array column.

I have a column in my Postgres table which contains sections.

 +----+-----------+
 | id |  sections |
 |----|-----------|
 |  1 |['A', 'B'] |
 +----+-----------+
 |  2 |['A', 'A'] |
 +----+-----------+

As you can see for id 2 I can insert two sections with the same text. I do not want to add duplicate text. I do not want duplicate sections in my column. Is there a way I can add an index on text array.

I saw the examples for int array but can't find anything for text array

I do not want to create the new function. I want to use the existing function in Postgres.

4
  • 2
    You can't create a unique index over an array to prevent overlapping array elements. Normalize your model, then it is really eas Commented Oct 3, 2018 at 11:03
  • 1
    You would need a trigger for that, but it would be costly. Normalize your model as @a_horse_with_no_name mentioned. Commented Oct 3, 2018 at 11:07
  • Do you want to disallow duplicate values in a single row? As in the example above you don't allow to insert ['A', 'A'] into row 2 but ['A', 'B'] would be allowed. Or do you want to disallow adding a row with array containing A altogether given that there is a row with array having A? Commented Oct 3, 2018 at 11:12
  • I want to disallow duplicate values in the single row. EDIT: Actually both will work. Commented Oct 3, 2018 at 11:15

2 Answers 2

2

You can append into the sections column and unnest with distinct element like this:

update class set sections = array(
    select distinct unnest(
        array_append(
            (select section from class where id = 2), 'A'))
    where id = 2)
Sign up to request clarification or add additional context in comments.

Comments

0

I like arays and do not always it good to normalize tables :-)

CREATE OR REPLACE FUNCTION is_not_unique(a int[]) RETURNS bool AS $f$
   SELECT array_upper(a, 1) = array_upper(
               (
                SELECT array_agg(DISTINCT u)
                  FROM unnest(a) AS u
          ), 1);
$f$ LANGUAGE sql;

CREATE TEMP TABLE a (a int[], CHECK (is_not_unique(a)));

Test it:

# INSERT INTO a VALUES (ARRAY[1]);
INSERT 0 1
# INSERT INTO a VALUES (ARRAY[1, 2]);
INSERT 0 1
# INSERT INTO a VALUES (ARRAY[1, 1]);
ERROR:  new row for relation "a" violates check constraint "a_a_check"
DETAIL:  Failing row contains ({1,1}).

2 Comments

For integer, I achieved the solution before this question. I am looking for a text array solution. Thanks for the help :)
The same for text

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.