Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PostgreSQL ON CONFLICT with a WHERE clause

Postgres documentation makes it seem like a WHERE clause is possible as an ON CONFLICT condition: https://www.postgresql.org/docs/9.5/static/sql-insert.html

I have not been able to get this working (if it's possible). Here is one of the many permutations I've tried:

INSERT INTO friends (id, dob, frn, status, "groupId", 
"createdAt", "updatedAt") 
VALUES ('1da04305-68ef-4dc1-be6c-
826ab83a6479', '1937-06-01T08:29:08-07:00', 100001, 'New', 'bc1567bc-
14ff-4ba2-b108-4cb2e0f0f768', NOW(), NOW()) 
ON CONFLICT 
    WHERE frn=100001 DO NOTHING

frn does not have any constraints, so the simpler syntax:

ON CONFLICT (frn) DO NOTHING

throws database errors. My hope is this is a simple syntax issue.

like image 803
smeckydev Avatar asked Jun 15 '17 15:06

smeckydev


People also ask

What is on conflict in PostgreSQL?

This topic describes how to use INSERT ON CONFLICT to overwrite data in AnalyticDB for PostgreSQL. The INSERT ON CONFLICT statement allows you to update an existing row that contains a primary key when you execute the INSERT statement to insert a new row that contains the same primary key.

What is the purpose of where clause in PostgreSQL?

The PostgreSQL WHERE clause is used to specify a condition while fetching the data from single table or joining with multiple tables. If the given condition is satisfied, only then it returns specific value from the table.

Does Postgres have Upsert?

PostgreSQL lets you either add or modify a record within a table depending on whether the record already exists. This is commonly known as an "upsert" operation (a portmanteau of "insert" and "update").

Does Postgres support with clause?

In PostgreSQL, the WITH query provides a way to write auxiliary statements for use in a larger query. It helps in breaking down complicated and large queries into simpler forms, which are easily readable.


1 Answers

The WHERE clause is subordinate to the ON CONFLICT (constraint) DO UPDATE SET ... clause. It only looks at the single row that violated the specified constraint when trying to INSERT.

A syntactically valid example:

INSERT INTO friends (
    id, 
    dob, frn, status,
    "groupId", "createdAt", "updatedAt"
) VALUES (
    '1da04305-68ef-4dc1-be6c-826ab83a6479',
    '1937-06-01T08:29:08-07:00', 100001, 'New',
    'bc1567bc-14ff-4ba2-b108-4cb2e0f0f768', NOW(), NOW()
) 
ON CONFLICT ("groupId", frn) DO UPDATE SET
    status='Revised', 
    "updatedAt"=NOW()
WHERE friends.status<>'Deleted';

Or as an operational example.

like image 159
gwaigh Avatar answered Oct 13 '22 18:10

gwaigh