I have this table schema on Postgres:
> \d+ users_types_brands
Table "public.users_types_brands"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
----------------+-----------------------------+-----------+----------+------------------------------------------------+---------+--------------+-------------
id | integer | | not null | nextval('users_types_brands_id_seq'::regclass) | plain | |
inserted_at | timestamp without time zone | | | now() | plain | |
updated_at | timestamp without time zone | | | now() | plain | |
users_types_id | bigint | | | | plain | |
brand_id | bigint | | not null | | plain | |
tasks_type_id | integer | | | | plain | |
Indexes:
"users_types_brands_pkey" PRIMARY KEY, btree (id)
"users_types_brands_users_types_id_brand_id_tasks_type_id_index" UNIQUE, btree (users_types_id, brand_id, tasks_type_id)
Foreign-key constraints:
"users_types_brands_users_types_id_fkey" FOREIGN KEY (users_types_id) REFERENCES users_types(id)
Access method: heap
Right now the table looks like this:
my_db=# select * from users_types_brands;
id | inserted_at | updated_at | users_types_id | brand_id | tasks_type_id
----+----------------------------+----------------------------+----------------+----------+---------------
12 | 2021-10-24 16:43:12.244026 | 2021-10-24 16:43:12.244026 | 2 | 112 | 8
14 | 2021-10-24 17:03:12.012874 | 2021-10-24 17:03:12.012874 | 2 | 111 | 9
(2 rows)
Of course, I can't insert a row like this:
my_db=# insert into users_types_brands (users_types_id, brand_id, tasks_type_id) values (2, 112, 8);
ERROR: duplicate key value violates unique constraint "users_types_brands_users_types_id_brand_id_tasks_type_id_index"
DETAIL: Key (users_types_id, brand_id, tasks_type_id)=(2, 112, 8) already exists.
But I can do this several times:
my_db=# insert into users_types_brands (users_types_id, brand_id) values (2, 112);
INSERT 0 1
And obtain this:
my_db=# select * from users_types_brands;
id | inserted_at | updated_at | users_types_id | brand_id | tasks_type_id
----+----------------------------+----------------------------+----------------+----------+---------------
12 | 2021-10-24 16:43:12.244026 | 2021-10-24 16:43:12.244026 | 2 | 112 | 8
14 | 2021-10-24 17:03:12.012874 | 2021-10-24 17:03:12.012874 | 2 | 111 | 9
16 | 2021-10-24 17:15:58.295428 | 2021-10-24 17:15:58.295428 | 2 | 112 |
17 | 2021-10-24 17:16:36.99971 | 2021-10-24 17:16:36.99971 | 2 | 112 |
(4 rows)
Now, according to the business rules, tasks_type_id can be null 👍
But how can I avoid creating repeated rows like the last two? One null tasks_type_id is OK, but not two or more.
Has anyone faced this before?
The COALESCE function returns the first of its arguments that is not null. Null is returned only if all arguments are null. It is often used to substitute a default value for null values when data is retrieved for display. But what I'm looking for is to not create the record Thank you, though 👍GROUP BY tasks_type_idif you are sure that othertasks_type_idwill appear one timeCREATE UNIQUE INDEX CONCURRENTLY users_types_brands_users_types_id_brand_id_tasks_type_id_index ON users_types_brands (users_types_id, brand_id, COALESCE(tasks_type_id, -1));Thanks, @Elikill58