What if your database could handle duplicates for you, silently and instantly?
Why Conditional INSERT with ON CONFLICT in PostgreSQL? - Purpose & Use Cases
Imagine you have a guest list for a party in a notebook. Every time a new guest arrives, you check the entire list to see if their name is already there before writing it down.
This manual check is slow and tiring. You might miss a name or write duplicates by mistake. It wastes time and causes confusion when the list grows.
Using Conditional INSERT with ON CONFLICT in PostgreSQL lets the database automatically check for duplicates and decide what to do without extra effort from you.
SELECT * FROM guests WHERE name = 'Alice'; -- If no result, then INSERT INTO guests (name) VALUES ('Alice');
INSERT INTO guests (name) VALUES ('Alice') ON CONFLICT (name) DO NOTHING;This lets you add new data safely and quickly, avoiding duplicates and errors automatically.
When a website registers users, it can try to add a new username but skip it if that username already exists, all in one simple command.
Manual duplicate checks are slow and error-prone.
Conditional INSERT with ON CONFLICT automates conflict handling.
It makes data insertion safer and more efficient.
Practice
ON CONFLICT DO NOTHING clause do in a PostgreSQL INSERT statement?Solution
Step 1: Understand ON CONFLICT behavior
TheON CONFLICT DO NOTHINGclause tells PostgreSQL to ignore the insert if a duplicate key conflict happens.Step 2: Compare with other conflict actions
UnlikeDO UPDATEwhich modifies existing rows,DO NOTHINGsimply skips the insert without error.Final Answer:
It skips inserting the row if a conflict occurs on a unique key. -> Option AQuick Check:
ON CONFLICT DO NOTHING = skip insert on duplicate [OK]
- Thinking DO NOTHING updates existing rows
- Assuming DO NOTHING deletes conflicting rows
- Believing DO NOTHING raises an error
id in PostgreSQL?Solution
Step 1: Identify correct ON CONFLICT syntax
PostgreSQL usesON CONFLICT (column) DO UPDATE SETto update on conflict.Step 2: Check syntax details
INSERT INTO table_name (id, val) VALUES (1, 'a') ON CONFLICT (id) DO UPDATE SET val = EXCLUDED.val; correctly usesEXCLUDED.valto refer to the new value and specifies the conflict column.Final Answer:
INSERT INTO table_name (id, val) VALUES (1, 'a') ON CONFLICT (id) DO UPDATE SET val = EXCLUDED.val; -> Option DQuick Check:
ON CONFLICT (id) DO UPDATE SET val = EXCLUDED.val [OK]
- Using MySQL syntax ON DUPLICATE KEY UPDATE
- Omitting conflict target column in ON CONFLICT
- Combining DO NOTHING with SET clause incorrectly
users(id SERIAL PRIMARY KEY, username TEXT UNIQUE, score INT), what will be the result of this query?INSERT INTO users (username, score) VALUES ('alice', 10) ON CONFLICT (username) DO UPDATE SET score = users.score + EXCLUDED.score RETURNING *;Assuming a row with username 'alice' and score 5 already exists.
Solution
Step 1: Understand ON CONFLICT DO UPDATE behavior
The query updates the existing row where username='alice' because of the conflict on username.Step 2: Calculate updated score
The update sets score = users.score + EXCLUDED.score = 5 + 10 = 15, and returns the updated row.Final Answer:
The existing row's score is updated to 15 and returned. -> Option BQuick Check:
ON CONFLICT DO UPDATE adds scores = 15 [OK]
- Thinking a new row is inserted despite conflict
- Expecting an error on duplicate key
- Assuming the row is deleted before insert
products(id INT UNIQUE, name TEXT UNIQUE), identify the error in this PostgreSQL query:INSERT INTO products (id, name) VALUES (1, 'Pen') ON CONFLICT DO UPDATE SET name = EXCLUDED.name;
Solution
Step 1: Check ON CONFLICT syntax
When usingDO UPDATE, PostgreSQL requires specifying the conflict target column or constraint.Step 2: Identify missing conflict target
The query lacks(id)or constraint name afterON CONFLICT, causing syntax error.Final Answer:
Missing conflict target column after ON CONFLICT. -> Option AQuick Check:
ON CONFLICT needs target column for DO UPDATE [OK]
- Omitting conflict target column
- Misusing EXCLUDED keyword
- Assuming WHERE clause is mandatory
email and last_login into a table users(email TEXT UNIQUE, last_login TIMESTAMP). If the email already exists, update last_login only if the new timestamp is more recent. Which query correctly implements this conditional update?Solution
Step 1: Understand conditional update with WHERE clause
PostgreSQL allows aWHEREclause inDO UPDATEto conditionally apply the update.Step 2: Check condition for updating last_login
INSERT INTO users (email, last_login) VALUES ('a@b.com', '2024-01-01') ON CONFLICT (email) DO UPDATE SET last_login = EXCLUDED.last_login WHERE EXCLUDED.last_login > users.last_login; updateslast_loginonly if the new timestamp is greater than the existing one, usingWHERE EXCLUDED.last_login > users.last_login.Final Answer:
INSERT INTO users (email, last_login) VALUES ('a@b.com', '2024-01-01') ON CONFLICT (email) DO UPDATE SET last_login = EXCLUDED.last_login WHERE EXCLUDED.last_login > users.last_login; -> Option CQuick Check:
Use WHERE in DO UPDATE for conditional update [OK]
- Forgetting WHERE clause for conditional update
- Using DO NOTHING with WHERE incorrectly
- Updating unconditionally without checking timestamps
Ready to prove it?
Pass the test and this pattern moves unknown
