0

I'm having trouble figuring out how to insert a row in a table exclusively if a specific condition is true using Postgres.

I've found a lot of answers that use CONFLICT, but the value I'm checking for isn't unique, so I can't do much with that. I've also tried IF ELSE but as far as I understand it Postgres doesn't support this?

This is my current query:

IF EXISTS (SELECT id FROM "Vote" as v WHERE v."createdAt" >= '2020-09-01' AND v."createdAt" < '2020-10-01' AND v."authorId" = 6667 )                                                                         
    PRINT 'do nothing'
ELSE 
    INSERT INTO "Vote" ("authorId", "serverId") VALUES (1, 1);

It returns:

ERROR:  syntax error at or near "IF"

Essentially I'm checking if a user has cast a vote between two dates, if that is true, then nothing should happen, if false the vote should be inserted in the table.

Is checking if something should be inserted and inserting it possible in a single query, or should I first check if the value exists and then run the insert query?

1 Answer 1

2

Using plain SQL:

INSERT INTO "Vote" ("authorId", "serverId")
SELECT 1, 1
WHERE NOT EXISTS (
    SELECT id
    FROM "Vote" as v
    WHERE
        v."createdAt" >= '2020-09-01' AND
        v."createdAt" < '2020-10-01' AND
        v."authorId" = 6667) 

There is no IF in the plain SQL, only in pl/sql

Sign up to request clarification or add additional context in comments.

8 Comments

This still seems to insert even though a record created between '2020-09-01' and '2020-10-01' exists
@Eight Was my mistake. Should be not exists. Already fixed.
@Eight There was a typo in the answer now corrected. Please try with the updated WHERE NOT EXISTS
I had completely missed your update, that works! Thank you so much. Will set as answer as soon as Stackoverflow allows me to :)
@Eight PS: Be careful about race condition. You can find solutions in the www
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.