Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgresql enforce unique two-way combination of columns

I'm trying to create a table that would enforce a unique combination of two columns of the same type - in both directions. E.g. this would be illegal:

col1 col2
   1    2
   2    1

I have come up with this, but it doesn't work:

database=> \d+ friend;
                                Table "public.friend"
    Column    |           Type           | Modifiers | Storage  | Stats target | Description
--------------+--------------------------+-----------+----------+--------------+-------------
 user_id_from | text                     | not null  | extended |              |
 user_id_to   | text                     | not null  | extended |              |
 status       | text                     | not null  | extended |              |
 sent         | timestamp with time zone | not null  | plain    |              |
 updated      | timestamp with time zone |           | plain    |              |
Indexes:
    "friend_pkey" PRIMARY KEY, btree (user_id_from, user_id_to)
    "friend_user_id_to_user_id_from_key" UNIQUE CONSTRAINT, btree (user_id_to, user_id_from)
Foreign-key constraints:
    "friend_status_fkey" FOREIGN KEY (status) REFERENCES friend_status(name)
    "friend_user_id_from_fkey" FOREIGN KEY (user_id_from) REFERENCES user_account(login)
    "friend_user_id_to_fkey" FOREIGN KEY (user_id_to) REFERENCES user_account(login)
Has OIDs: no

Is it possible to write this without triggers or any advanced magic, using constraints only?

like image 996
tadeas Avatar asked May 04 '15 18:05

tadeas


People also ask

How do you make two columns unique in PostgreSQL?

In Postgresql, we can make two-column as unique using the UNIQUE keyword or function. Let's create a table named two_unq. CREATE TABLE emp_data ( id SERIAL, emp_name VARCHAR , email VARCHAR (50), UNIQUE(emp_name,email )); In the above code, we are creating emp_name, email as the unique column using the UNIQUE().

How do I create a unique two column combination in sqlite?

To define a UNIQUE constraint, you use the UNIQUE keyword followed by one or more columns. You can define a UNIQUE constraint at the column or the table level. Only at the table level, you can define a UNIQUE constraint across multiple columns.

Can Unique Key have multiple NULL values in PostgreSQL?

While the SQL standard allows multiple nulls in a unique column, and that is how Postgres behaves, some database systems (e.g. MS SQL) allow only a single null in such cases.


1 Answers

A variation on Neil's solution which doesn't need an extension is:

create table friendz (
  from_id int,
  to_id int
);

create unique index ifriendz on friendz(greatest(from_id,to_id), least(from_id,to_id));

Neil's solution lets you use an arbitrary number of columns though.

We're both relying on using expressions to build the index which is documented https://www.postgresql.org/docs/current/indexes-expressional.html

like image 153
Gary Avatar answered Oct 12 '22 21:10

Gary