What if you could add or update data with one simple command and never worry about duplicates again?
Why INSERT ON CONFLICT (upsert) in PostgreSQL? - Purpose & Use Cases
Imagine you have a guest list for a party in a notebook. You want to add new guests, but if someone is already on the list, you want to update their details instead of writing them twice.
Manually checking if a guest is already on the list before adding or updating takes a lot of time and can cause mistakes like duplicates or missing updates.
INSERT ON CONFLICT lets you add new data or update existing data in one simple step, so you never have duplicates and always keep your list accurate.
DO $$ BEGIN IF EXISTS (SELECT 1 FROM guests WHERE id = 1) THEN UPDATE guests SET name = 'Alice' WHERE id = 1; ELSE INSERT INTO guests (id, name) VALUES (1, 'Alice'); END IF; END $$;
INSERT INTO guests (id, name) VALUES (1, 'Alice') ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name;
This makes managing data fast, safe, and simple, even when many changes happen at once.
When a website registers users, it can add new users or update existing user info without errors or duplicates using INSERT ON CONFLICT.
Manually checking for existing data is slow and error-prone.
INSERT ON CONFLICT combines insert and update in one command.
It keeps data clean and operations efficient.
Practice
INSERT ON CONFLICT clause do in PostgreSQL?Solution
Step 1: Understand the purpose and behavior of INSERT ON CONFLICT
This clause helps handle duplicate key conflicts during insert operations by allowing an update instead of error. It either updates the existing row or ignores the insert, preventing errors.Final Answer:
It inserts a new row or updates existing row if a conflict occurs. -> Option AQuick Check:
INSERT ON CONFLICT = Insert or update [OK]
- Confusing ON CONFLICT with DELETE
- Assuming it only inserts without update
- Thinking it creates new tables
price on conflict for a table products with unique id?Solution
Step 1: Check PostgreSQL syntax for upsert and identify correct usage of EXCLUDED
PostgreSQL uses ON CONFLICT (column) DO UPDATE SET with EXCLUDED to refer to new values. INSERT INTO products (id, price) VALUES (1, 100) ON CONFLICT (id) DO UPDATE SET price = EXCLUDED.price; correctly uses EXCLUDED.price to update the price on conflict of id.Final Answer:
INSERT INTO products (id, price) VALUES (1, 100) ON CONFLICT (id) DO UPDATE SET price = EXCLUDED.price; -> Option CQuick Check:
Correct syntax uses ON CONFLICT (id) DO UPDATE SET with EXCLUDED [OK]
- Using MySQL syntax ON DUPLICATE KEY
- Forgetting EXCLUDED keyword
- Using DO DELETE which is invalid
users(id INT PRIMARY KEY, name TEXT, age INT) with data:(1, 'Alice', 30)What will be the result of this query?
INSERT INTO users (id, name, age) VALUES (1, 'Alice', 31) ON CONFLICT (id) DO UPDATE SET age = EXCLUDED.age RETURNING *;
Solution
Step 1: Understand the existing data/conflict and apply ON CONFLICT DO UPDATE
Row with id=1 exists with age=30, new insert tries age=31 causing conflict on id. It updates age to EXCLUDED.age (31) and returns the updated row.Final Answer:
[{id:1, name:'Alice', age:31}] -> Option BQuick Check:
ON CONFLICT updates age to 31 and returns updated row [OK]
- Expecting error on duplicate key
- Thinking old age remains unchanged
- Assuming empty result on update
INSERT INTO inventory (product_id, quantity) VALUES (10, 5) ON CONFLICT (product_id) DO UPDATE quantity = quantity + EXCLUDED.quantity;
Solution
Step 1: Review ON CONFLICT DO UPDATE syntax and identify missing SET keyword
The DO UPDATE clause requires SET keyword before specifying column updates. The query misses SET before 'quantity = quantity + EXCLUDED.quantity', causing syntax error.Final Answer:
Missing SET keyword before update expressions. -> Option DQuick Check:
DO UPDATE requires SET before column assignments [OK]
- Omitting SET keyword in DO UPDATE
- Misusing EXCLUDED keyword
- Confusing DO NOTHING and DO UPDATE
users(id, name, score) but if the id exists, update the score only if the new score is higher. Which query correctly implements this?Solution
Step 1: Understand conditional update on conflict and use WHERE clause in DO UPDATE
You want to update score only if new score is greater than existing score. INSERT INTO users (id, name, score) VALUES (2, 'Bob', 50) ON CONFLICT (id) DO UPDATE SET score = EXCLUDED.score WHERE EXCLUDED.score > users.score; uses WHERE EXCLUDED.score > users.score to conditionally update score correctly.Final Answer:
INSERT INTO users (id, name, score) VALUES (2, 'Bob', 50) ON CONFLICT (id) DO UPDATE SET score = EXCLUDED.score WHERE EXCLUDED.score > users.score; -> Option AQuick Check:
Conditional update uses WHERE clause in DO UPDATE [OK]
- Updating unconditionally without WHERE
- Using DO NOTHING with WHERE (invalid)
- Setting score to old value mistakenly
Ready to prove it?
Pass the test and this pattern moves unknown
